当前位置:网站首页>AXI_ Round_ Robin_ Arbiter design - aw and W channels

AXI_ Round_ Robin_ Arbiter design - aw and W channels

2022-06-23 14:51:00 Starry and


1. State machine design

Based on the state machine , The idea is to receive a package AW Channel data , Record its len, And then according to len and awid Receive corresponding AXI Master Of W Channel data , Guarantee AW Channels and W The channel sequence is consistent .

 Insert picture description here

How does the weight change ? What I think here is Every time AW and W The channel completes one-time data collection , The weight changes once . Make sure AW Acceptance and W Reception must come from the same AXI Master

1.1. WAIT_AW

Waiting for a AW Channel and AXI Slave The handshake is complete , You can go to the next state

according to req Output grant

Here req In fact, it's all about AXI Master Of awvalid Composed of many bit data , and grant Is the result of arbitration . Pay attention to WAIT_AW The state does not change

State transition conditions :AW The channel handshake is complete

Note that the state transition condition of the original algorithm is req When something changes, it shifts , But here you need something Master Of awvalid Is high and awready Handshake only when the signal is high , Here's the picture

 Insert picture description here

prio In fact, it is the weight . although req Changes have taken place in the middle , But the condition of state transition is the same as Master0 The condition is not transferred until the handshake is completed .

Be careful AW A channel is simply a one-time transmission of multiple control messages , No burst,awready&awvalid One effective clap can complete the handshake .
into WAIT_W Post state awready It should not be raised , Must wait from WAIT_W go back to WAIT_AW To pull it higher .

1.2. WAIT_W

Then enter WAIT_W state , Before WAIT_AW With which Master Finished shaking hands , This is what we have to wait for Master Of W The channel handshake is completed WAIT_W state .

grant keep , Accept W Channel data

there grant Must be with WAIT_AW When the handshake is completed grant Agreement , At the same time, always accept W Data from the channel

State transition conditions :W The channel handshake is complete

because Master Is constant , So just look at that Master Of wlast that will do , This signal represents the last data .

 Insert picture description here

After the handshake is done , Return to WAIT_AW state . Note that this time prio The weight should also be based on grant Make corrections , meanwhile grant It can't be maintained any longer , into WAIT_AW After that, according to awvalid_mst Make combinational logic output

in summary , The state machine becomes

 Insert picture description here

1.3. Code

module axi_round_robin_arbiter_aw_w #(
	parameter AWID_WIDTH				= 8,
	parameter AWADDR_WIDTH 				= 16,
	parameter WDATA_WIDTH 				= 16,
	parameter MAX_PRIO_INITIAL_INDEX 	= 0
	)(
	input							aclk,
	input							arstn,
	
	//AW CHANNEL
	input	[(AWID_WIDTH+2)*4-1:0]		awid_mst,
	input	[AWADDR_WIDTH*4-1:0]	awaddr_mst,
	input	[8*4-1:0]				awlen_mst,
	input	[3*4-1:0]				awsize_mst,
	input	[2*4-1:0]				awburst_mst,
	input	[1*4-1:0]				awvalid_mst,
	output	[1*4-1:0]				awready_mst,
	output	[(AWID_WIDTH+2)-1:0]		awid,
	output	[AWADDR_WIDTH-1:0]		awaddr,
	output	[8-1:0]					awlen,
	output	[3-1:0]					awsize,
	output	[2-1:0]					awburst,
	output							awvalid,
	input							awready,
	
	//W CHANNEL
	input	[WDATA_WIDTH*4-1:0]		wdata_mst,
	input	[1*4-1:0]				wlast_mst,
	input	[1*4-1:0]				wvalid_mst,
	output	[1*4-1:0]				wready_mst,
	output	[WDATA_WIDTH-1:0]		wdata,
	output	[1-1:0]					wlast,
	output	[1-1:0]					wvalid,
	input	[1-1:0]					wready
	);

localparam	WAIT_AW = 1'b0;	
localparam	WAIT_W  = 1'b1;	
	

reg		[4-1:0]					cur_state;
reg		[4-1:0]					nxt_state;
reg		[4-1:0]					grant;
reg		[4-1:0]					grant_tmp;
reg		[4-1:0]					prio;
reg								wvalid_mst_cs;
reg								wlast_mst_cs;
wire	[4-1:0]					inital_state;
wire	[4:0]					res1;
wire	[4:0]					res2;

assign inital_state = {
    {
    (4-MAX_PRIO_INITIAL_INDEX-1){
    1'b0}},1'b1,{
    MAX_PRIO_INITIAL_INDEX{
    1'b0}}};

[email protected](posedge aclk or negedge arstn) begin
	if(!arstn)
		cur_state <= WAIT_AW;
	else 
		cur_state <= nxt_state;
end

[email protected](*) begin
	case(cur_state)
		WAIT_AW:
			if((|awvalid_mst) && awready)
				nxt_state = WAIT_W;
			else
				nxt_state = WAIT_AW;
		WAIT_W:
			if(wvalid_mst_cs && wlast_mst_cs && wready)
				nxt_state = WAIT_AW;
			else
				nxt_state = WAIT_W;
		default:	nxt_state = WAIT_AW;
	endcase
end


[email protected](posedge aclk or negedge arstn) begin
	if(!arstn)
		prio <= inital_state;
	else if(cur_state == WAIT_W && wvalid_mst_cs && wlast_mst_cs && wready) 
		prio <= (grant[3])? 4'b1:(grant << 1);
end

[email protected](*) begin
	if(cur_state == WAIT_AW)
		wlast_mst_cs = 1'b0;
	else begin
		case(grant)
			4'b0001:
				wlast_mst_cs = wlast_mst[0];
			4'b0010:
				wlast_mst_cs = wlast_mst[1];
			4'b0100:
				wlast_mst_cs = wlast_mst[2];
			4'b1000:                      
				wlast_mst_cs = wlast_mst[3];
			default:
				wlast_mst_cs = 1'b0;
		endcase
	end
end

[email protected](*) begin
	if(cur_state == WAIT_W)
		wvalid_mst_cs = 1'b0;
	else begin
		case(grant)
			4'b0001:
				wvalid_mst_cs = wvalid_mst[0];
			4'b0010:
				wvalid_mst_cs = wvalid_mst[1];
			4'b0100:
				wvalid_mst_cs = wvalid_mst[2];
			4'b1000:                      
				wvalid_mst_cs = wvalid_mst[3];
			default:
				wvalid_mst_cs = 1'b0;
		endcase
	end
end

[email protected](posedge aclk or negedge arstn) begin
	if(!arstn)
		grant_tmp <= 'd0;
	else if(cur_state == WAIT_AW && (|awvalid_mst) && awready)
		grant_tmp <= grant;
end


assign res1 = {
    1'b0,~awvalid_mst} + {
    1'b0,prio};

assign res2 = res1[4] + res1;

[email protected](*) begin
	if(cur_state == WAIT_AW)
		grant = awvalid_mst & res2;
	else
		grant = grant_tmp;
end




//-----------------AW channel chip select--------------------------

reg		[(AWID_WIDTH+2)-1:0]		awid_r;
reg		[AWADDR_WIDTH-1:0]		awaddr_r;
reg		[8-1:0]					awlen_r;
reg		[3-1:0]					awsize_r;
reg		[2-1:0]					awburst_r;
reg								awvalid_r;
reg		[1*4-1:0]				awready_mst_r;


[email protected](*) begin
	if(cur_state == WAIT_AW) begin
		case(grant)
			4'b0001:
				awid_r = awid_mst[(AWID_WIDTH+2)-1:0];
			4'b0010:
				awid_r = awid_mst[(AWID_WIDTH+2)*2-1:(AWID_WIDTH+2)];
			4'b0100:
				awid_r = awid_mst[(AWID_WIDTH+2)*3-1:(AWID_WIDTH+2)*2];
			4'b1000:
				awid_r = awid_mst[(AWID_WIDTH+2)*4-1:(AWID_WIDTH+2)*3];
			default:
				awid_r = 'd0;
		endcase
	end
	else
		awid_r = 'd0;	
end

assign awid = awid_r;

[email protected](*) begin
	if(cur_state == WAIT_AW) begin
		case(grant)
			4'b0001:
				awaddr_r = awaddr_mst[AWADDR_WIDTH-1:0];
			4'b0010:
				awaddr_r = awaddr_mst[AWADDR_WIDTH*2-1:AWADDR_WIDTH];
			4'b0100:
				awaddr_r = awaddr_mst[AWADDR_WIDTH*3-1:AWADDR_WIDTH*2];
			4'b1000:
				awaddr_r = awaddr_mst[AWADDR_WIDTH*4-1:AWADDR_WIDTH*3];
			default:
				awaddr_r = 'd0;
		endcase
	end
	else
		awaddr_r = 'd0;
end

assign awaddr = awaddr_r;

[email protected](*) begin
	if(cur_state == WAIT_AW) begin
		case(grant)
			4'b0001:
				awlen_r = awlen_mst[8-1:0];
			4'b0010:
				awlen_r = awlen_mst[8*2-1:8];
			4'b0100:
				awlen_r = awlen_mst[8*3-1:8*2];
			4'b1000:
				awlen_r = awlen_mst[8*4-1:8*3];
			default:
				awlen_r = 'd0;
		endcase
	end
	else
		awlen_r = 'd0;
end

assign awlen = awlen_r;

[email protected](*) begin
	if(cur_state == WAIT_AW) begin
		case(grant)
			4'b0001:
				awsize_r = awsize_mst[3-1:0];
			4'b0010:
				awsize_r = awsize_mst[3*2-1:3];
			4'b0100:
				awsize_r = awsize_mst[3*3-1:3*2];
			4'b1000:
				awsize_r = awsize_mst[3*4-1:3*3];
			default:
				awsize_r = 'd0;
		endcase
	end
	else
		awsize_r = 'd0;
end

assign awsize = awsize_r;

[email protected](*) begin
	if(cur_state == WAIT_AW) begin
		case(grant)
			4'b0001:
				awburst_r = awburst_mst[2-1:0];
			4'b0010:
				awburst_r = awburst_mst[2*2-1:2];
			4'b0100:
				awburst_r = awburst_mst[2*3-1:2*2];
			4'b1000:
				awburst_r = awburst_mst[2*4-1:2*3];
			default:
				awburst_r = 'd0;
		endcase
	end
	else
		awburst_r = 'd0;
end

assign awburst = awburst_r;

[email protected](*) begin
	if(cur_state == WAIT_AW) begin	
		case(grant)
			4'b0001:
				awvalid_r = awvalid_mst[1-1:0];
			4'b0010:
				awvalid_r = awvalid_mst[1*2-1:1];
			4'b0100:
				awvalid_r = awvalid_mst[1*3-1:1*2];
			4'b1000:
				awvalid_r = awvalid_mst[1*4-1:1*3];
			default:
				awvalid_r = 'd0;
		endcase
	end
	else
		awvalid_r = 'd0;
end

assign awvalid = awvalid_r;

[email protected](*) begin
	if(cur_state == WAIT_AW)
		awready_mst_r = awready << grant;
	else
		awready_mst_r = 'd0;
end

assign awready_mst = awready_mst_r;


//-----------------W channel chip select--------------------------

reg		[1*4-1:0]				wready_mst_r;
reg		[WDATA_WIDTH-1:0]		wdata_r;
reg		[1-1:0]					wlast_r;
reg		[1-1:0]					wvalid_r;


[email protected](*) begin
	if(cur_state == WAIT_AW) 
		wready_mst_r = 'd0;
	else 
		wready_mst_r = wready << grant;
end

assign wready_mst = wready_mst_r;

[email protected](*) begin
	if(cur_state == WAIT_AW) 
		wdata_r = 'd0;
	else begin
		case(grant)
			4'b0001:
				wdata_r = wdata_mst[WDATA_WIDTH-1:0];
			4'b0010:
				wdata_r = wdata_mst[WDATA_WIDTH*2-1:WDATA_WIDTH];
			4'b0100:
				wdata_r = wdata_mst[WDATA_WIDTH*3-1:WDATA_WIDTH*2];
			4'b1000:
				wdata_r = wdata_mst[WDATA_WIDTH*4-1:WDATA_WIDTH*3];
			default:
				wdata_r = 'd0;
		endcase
	end
end

assign wdata = wdata_r;

[email protected](*) begin
	if(cur_state == WAIT_AW) 
		wlast_r = 'd0;
	else begin
		case(grant)
			4'b0001:
				wlast_r = wlast_mst[0];
			4'b0010:
				wlast_r = wlast_mst[1];
			4'b0100:
				wlast_r = wlast_mst[2];
			4'b1000:
				wlast_r = wlast_mst[3];
			default:
				wlast_r = 'd0;
		endcase
	end
end

assign wlast = wlast_r;

[email protected](*) begin
	if(cur_state == WAIT_AW) 
		wvalid_r = 'd0;
	else begin
		case(grant)
			4'b0001:
				wvalid_r = wvalid_mst[0];
			4'b0010:
				wvalid_r = wvalid_mst[1];
			4'b0100:
				wvalid_r = wvalid_mst[2];
			4'b1000:
				wvalid_r = wvalid_mst[3];
			default:
				wvalid_r = 'd0;
		endcase
	end
end

assign wvalid = wvalid_r;

endmodule

2. Change the state machine to flow line

You can find , In the design of the above state machine ,WAIT_AW In the state of AXI Master Of AW Channels and AXI Slave Of AW Channel signals can communicate with each other , But this time W The channel is blocked . stay WAIT_W State, ,W The signal of the channel is opened , and AW The signal of the channel is blocked .

Now I think of it , stay WAIT_W State, ,AW The passage is directly blocked , Can you let go , Give Way AW Channel normal communication , namely WAIT_AW and WAIT_W The two states are parallel ?

Pipeline design can be transformed from state machine , For example, multiplier can be divided into first order bit Multiply 、 Then add them by dislocation , Then, can we make a list of the new data when we add them out of place bit Multiply ? Sure , According to this idea, the state machine is optimized into a pipeline .
RTL Multiplier IP Design
Of course, not all state machines can be fully optimized into pipelines , Some cannot be optimized at all ( for example USART), Some states can be optimized by pipeline .

that How to WAIT_AW and WAIT_W In parallel ?

AW Channels and W The root cause of channel collaborative design is ,W There's no channel wid, therefore AW The receiving order of the channel must be the same as W The receiving order of the channel is consistent .

therefore , Just every time AW Complete the handshake once , Record the handshake at this time Master Who is it? , namely grant. Each handshake will grant Put in FIFO, and W As for the channel, every time the handshake is completed, it starts from FIFO read out grant Know what to interact with next time Master, That's it AW Channels and W The running water of the passage .

Since the two channels use synchronization FIFO Isolation , Then it can be divided into two modules

 Insert picture description here

2.1. axi_round_robin_arbiter_aw

AW Channel arbitration is easier to say , But still use the state machine , The status here should be changed to FIFO Is it full ,FIFO Full communication will be blocked .

Code

module axi_round_robin_arbiter_aw #(
	parameter AWID_WIDTH				= 8,
	parameter AWADDR_WIDTH 				= 16,
	parameter MAX_PRIO_INITIAL_INDEX 	= 0
	)(
	input							aclk,
	input							arstn,
	
	//AW CHANNEL
	input	[(AWID_WIDTH+2)*4-1:0]	awid_mst,
	input	[AWADDR_WIDTH*4-1:0]	awaddr_mst,
	input	[8*4-1:0]				awlen_mst,
	input	[3*4-1:0]				awsize_mst,
	input	[2*4-1:0]				awburst_mst,
	input	[1*4-1:0]				awvalid_mst,
	output	[1*4-1:0]				awready_mst,
	output	[(AWID_WIDTH+2)-1:0]	awid,
	output	[AWADDR_WIDTH-1:0]		awaddr,
	output	[8-1:0]					awlen,
	output	[3-1:0]					awsize,
	output	[2-1:0]					awburst,
	output							awvalid,
	input							awready,
	
	input							grant_fifo_full,
	output	[4-1:0]					grant,
	output							grant_val
	);

reg		[4-1:0]					cur_state;
reg		[4-1:0]					nxt_state;
wire	[4-1:0]					inital_state;
wire	[4:0]					res1;
wire	[4:0]					res2;

assign inital_state = {
    {
    (4-MAX_PRIO_INITIAL_INDEX-1){
    1'b0}},1'b1,{
    MAX_PRIO_INITIAL_INDEX{
    1'b0}}};

[email protected](posedge aclk or negedge arstn) begin
	if(!arstn)
		cur_state <= inital_state;
	else 
		cur_state <= nxt_state;
end

[email protected](*) begin
	if(grant_val) begin
		if(grant[3])
			nxt_state = 4'b1;
		else
			nxt_state = grant << 1;
	end
	else
		nxt_state = cur_state;
end


assign res1 = {
    1'b0,~awvalid_mst} + {
    1'b0,cur_state};

assign res2 = res1[4] + res1;

assign grant = awvalid_mst & res2;

assign grant_val = awvalid && awready;



//-----------------AW channel chip select--------------------------

reg		[(AWID_WIDTH+2)-1:0]	awid_r;
reg		[AWADDR_WIDTH-1:0]		awaddr_r;
reg		[8-1:0]					awlen_r;
reg		[3-1:0]					awsize_r;
reg		[2-1:0]					awburst_r;
reg								awvalid_r;
reg		[1*4-1:0]				awready_mst_r;


[email protected](*) begin
	if(!grant_fifo_full) begin
		case(grant)
			4'b0001:
				awid_r = awid_mst[(AWID_WIDTH+2)-1:0];
			4'b0010:
				awid_r = awid_mst[(AWID_WIDTH+2)*2-1:(AWID_WIDTH+2)];
			4'b0100:
				awid_r = awid_mst[(AWID_WIDTH+2)*3-1:(AWID_WIDTH+2)*2];
			4'b1000:
				awid_r = awid_mst[(AWID_WIDTH+2)*4-1:(AWID_WIDTH+2)*3];
			default:
				awid_r = 'd0;
		endcase
	end
	else
		awid_r = 'd0;	
end

assign awid = awid_r;

[email protected](*) begin
	if(!grant_fifo_full) begin
		case(grant)
			4'b0001:
				awaddr_r = awaddr_mst[AWADDR_WIDTH-1:0];
			4'b0010:
				awaddr_r = awaddr_mst[AWADDR_WIDTH*2-1:AWADDR_WIDTH];
			4'b0100:
				awaddr_r = awaddr_mst[AWADDR_WIDTH*3-1:AWADDR_WIDTH*2];
			4'b1000:
				awaddr_r = awaddr_mst[AWADDR_WIDTH*4-1:AWADDR_WIDTH*3];
			default:
				awaddr_r = 'd0;
		endcase
	end
	else
		awaddr_r = 'd0;
end

assign awaddr = awaddr_r;

[email protected](*) begin
	if(!grant_fifo_full) begin
		case(grant)
			4'b0001:
				awlen_r = awlen_mst[8-1:0];
			4'b0010:
				awlen_r = awlen_mst[8*2-1:8];
			4'b0100:
				awlen_r = awlen_mst[8*3-1:8*2];
			4'b1000:
				awlen_r = awlen_mst[8*4-1:8*3];
			default:
				awlen_r = 'd0;
		endcase
	end
	else
		awlen_r = 'd0;
end

assign awlen = awlen_r;

[email protected](*) begin
	if(!grant_fifo_full) begin
		case(grant)
			4'b0001:
				awsize_r = awsize_mst[3-1:0];
			4'b0010:
				awsize_r = awsize_mst[3*2-1:3];
			4'b0100:
				awsize_r = awsize_mst[3*3-1:3*2];
			4'b1000:
				awsize_r = awsize_mst[3*4-1:3*3];
			default:
				awsize_r = 'd0;
		endcase
	end
	else
		awsize_r = 'd0;
end

assign awsize = awsize_r;

[email protected](*) begin
	if(!grant_fifo_full) begin
		case(grant)
			4'b0001:
				awburst_r = awburst_mst[2-1:0];
			4'b0010:
				awburst_r = awburst_mst[2*2-1:2];
			4'b0100:
				awburst_r = awburst_mst[2*3-1:2*2];
			4'b1000:
				awburst_r = awburst_mst[2*4-1:2*3];
			default:
				awburst_r = 'd0;
		endcase
	end
	else
		awburst_r = 'd0;
end

assign awburst = awburst_r;

[email protected](*) begin
	if(!grant_fifo_full) begin	
		case(grant)
			4'b0001:
				awvalid_r = awvalid_mst[1-1:0];
			4'b0010:
				awvalid_r = awvalid_mst[1*2-1:1];
			4'b0100:
				awvalid_r = awvalid_mst[1*3-1:1*2];
			4'b1000:
				awvalid_r = awvalid_mst[1*4-1:1*3];
			default:
				awvalid_r = 'd0;
		endcase
	end
	else
		awvalid_r = 'd0;
end

assign awvalid = awvalid_r;

[email protected](*) begin
	if(!grant_fifo_full)
		awready_mst_r = awready << grant;
	else
		awready_mst_r = 'd0;
end

assign awready_mst = awready_mst_r;

endmodule

2.2. axi_round_robin_arbiter_w

about W In terms of channels , Must be from FIFO read out grant Talent and grant Stipulated Master handshake , So we still follow the design process of state machine , There are two states

 Insert picture description here

RD_GRANT

Read all the time in this state FIFO, meanwhile W The passage is blocked , until grant Read out

 Insert picture description here

HANDSHAKE

here grant Will always keep , according to grant choice Master Wait for the handshake to complete .

 Insert picture description here

Code

module axi_round_robin_arbiter_w #(
	parameter WDATA_WIDTH 				= 16,
	parameter MAX_PRIO_INITIAL_INDEX 	= 0
	)(
	input							aclk,
	input							arstn,
	
	//W CHANNEL
	input	[WDATA_WIDTH*4-1:0]		wdata_mst,
	input	[1*4-1:0]				wlast_mst,
	input	[1*4-1:0]				wvalid_mst,
	output	[1*4-1:0]				wready_mst,
	output	[WDATA_WIDTH-1:0]		wdata,
	output	[1-1:0]					wlast,
	output	[1-1:0]					wvalid,
	input	[1-1:0]					wready,
	
	output							fifo_rd_en,
	input							fifo_empty,
	input		[4-1:0]				grant,
	input							grant_val
	);

localparam	IDLE 		= 2'b00;	
localparam	RD_GRANT  	= 2'b01;	
localparam	HANDSHAKE  	= 2'b11;	
	

reg		[1:0]		cur_state;
reg		[1:0]		nxt_state;
reg					fifo_rd_en_r;

[email protected](posedge aclk or negedge arstn) begin
	if(!arstn)
		cur_state <= IDLE;
	else 
		cur_state <= nxt_state;
end

[email protected](*) begin
	case(cur_state)
		IDLE:
			nxt_state = RD_GRANT;
		RD_GRANT:
			if(grant_val)
				nxt_state = HANDSHAKE;
			else
				nxt_state = RD_GRANT;
		HANDSHAKE:
			if(wlast && wready)
				nxt_state = HANDSHAKE;
			else
				nxt_state = RD_GRANT;
		default:	nxt_state = IDLE;
	endcase
end


[email protected](posedge aclk or negedge arstn) begin
	if(!arstn)
		fifo_rd_en_r <= 1'b0;
	else if(cur_state == IDLE)
		fifo_rd_en_r <= 1'b1;
	else if(cur_state == RD_GRANT) begin
			if(!fifo_empty)
				fifo_rd_en_r <= 1'b0;
	end
	else if(cur_state == HANDSHAKE) begin
			if(wlast && wready)
				fifo_rd_en_r <= 1'b1;
	end		
end

assign fifo_rd_en = fifo_rd_en_r;


//-----------------W channel chip select--------------------------

reg		[1*4-1:0]				wready_mst_r;
reg		[WDATA_WIDTH-1:0]		wdata_r;
reg		[1-1:0]					wlast_r;
reg		[1-1:0]					wvalid_r;


[email protected](*) begin
	if(!cur_state[0]) 								//(cur_state == IDLE) && (cur_state == RD_GRANT) 
		wready_mst_r = 'd0;
	else 
		wready_mst_r = wready << grant;
end

assign wready_mst = wready_mst_r;

[email protected](*) begin
	if(!cur_state[0]) 
		wdata_r = 'd0;
	else begin
		case(grant)
			4'b0001:
				wdata_r = wdata_mst[WDATA_WIDTH-1:0];
			4'b0010:
				wdata_r = wdata_mst[WDATA_WIDTH*2-1:WDATA_WIDTH];
			4'b0100:
				wdata_r = wdata_mst[WDATA_WIDTH*3-1:WDATA_WIDTH*2];
			4'b1000:
				wdata_r = wdata_mst[WDATA_WIDTH*4-1:WDATA_WIDTH*3];
			default:
				wdata_r = 'd0;
		endcase
	end
end

assign wdata = wdata_r;

[email protected](*) begin
	if(!cur_state[0]) 
		wlast_r = 'd0;
	else begin
		case(grant)
			4'b0001:
				wlast_r = wlast_mst[0];
			4'b0010:
				wlast_r = wlast_mst[1];
			4'b0100:
				wlast_r = wlast_mst[2];
			4'b1000:
				wlast_r = wlast_mst[3];
			default:
				wlast_r = 'd0;
		endcase
	end
end

assign wlast = wlast_r;

[email protected](*) begin
	if(!cur_state[0]) 
		wvalid_r = 'd0;
	else begin
		case(grant)
			4'b0001:
				wvalid_r = wvalid_mst[0];
			4'b0010:
				wvalid_r = wvalid_mst[1];
			4'b0100:
				wvalid_r = wvalid_mst[2];
			4'b1000:
				wvalid_r = wvalid_mst[3];
			default:
				wvalid_r = 'd0;
		endcase
	end
end

assign wvalid = wvalid_r;

endmodule
原网站

版权声明
本文为[Starry and]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/174/202206231349273328.html