当前位置:网站首页>AXI_Round_Robin_Arbiter 设计 - AW、W通道部分

AXI_Round_Robin_Arbiter 设计 - AW、W通道部分

2022-06-23 13:50:00 Starry丶


1. 状态机设计

还是基于状态机,思路是收到了一包AW通道的数据,记录下它的len,然后根据len和awid收相应的AXI Master的W通道数据,保证AW通道和W通道顺序一致。

在这里插入图片描述

那权重怎么变化呢?此处想的是每AW和W通道完成一次收数,权重变化一次。注意要保证AW接受和W接收必须来自同一个AXI Master

1.1. WAIT_AW

等待某个AW通道与AXI Slave握手完成,即可转入下一状态

根据req输出grant

此处的req其实就是各AXI Master的awvalid组成的多bit数据,而grant就是仲裁的结果。注意在WAIT_AW时状态不发生变化

状态转移条件:AW通道握手完成

注意原算法的状态转移条件是req发生变化就转移,但在此处需要某个Master的awvalid为高且awready信号拉高才能握手,如下图

在这里插入图片描述

prio其实就是权重。虽然req中途发生了变化,但状态转移的条件是与Master0握手完成才转移条件。

注意AW通道只是一次性传递多个控制信息,不是burst,awready&awvalid有效一拍即可完成握手。
转入WAIT_W状态后awready不应再拉高,必须等待从WAIT_W回到WAIT_AW才能再拉高。

1.2. WAIT_W

然后进入WAIT_W状态,之前WAIT_AW状态下与哪个Master完成了握手,此处就必须等这个Master的W通道握手完成才能结束WAIT_W状态。

grant保持,接受W通道数据

这里的grant必须要与WAIT_AW状态下握手完成时的grant一致,同时要一直接受W通道来的数据

状态转移条件:W通道握手完成

由于Master是固定的,所以只需看那个Master的wlast即可,这个信号表示最后一个数据。

在这里插入图片描述

握手完成之后,重新回到WAIT_AW状态。注意此时prio权重也要根据grant作修正,同时grant不能再继续保持了,转入WAIT_AW后要根据awvalid_mst作组合逻辑输出

综上所述,状态机变成

在这里插入图片描述

1.3. 代码

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


alwa[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. 状态机改流水

可以发现,在上述状态机的设计中,WAIT_AW状态时AXI Master的AW通道和AXI Slave的AW通道信号能够相互通信,但此时W通道被阻断。在WAIT_W状态下,W通道的信号被打通,而AW通道的信号被阻隔。

此时想到,在WAIT_W状态下,AW通道直接被阻隔了,那能不能放开,让AW通道正常通信,即WAIT_AW和WAIT_W两种状态并行呢?

流水线设计可从状态机改造而来,例如乘法器就可分为先单bit相乘、再错位相加,那么在错位相加的时候可不可以对新的数据进行单bit相乘呢?可以,按照这个思路就将状态机优化成流水线了。
RTL乘法器IP设计
当然不是所有的状态机都可以完全优化成流水线,有的完全不能优化(例如USART),有的可以将部分状态进行流水优化。

那么 怎么将WAIT_AW和WAIT_W并行起来呢?

AW通道和W通道协同设计的根本原因是,W通道没有wid,所以AW通道的收数顺序必须与W通道的收数顺序一致。

所以,只需每次AW完成握手一次,记录下此时握手的Master是谁,即grant。每完成一次握手就将grant放入FIFO,而W通道呢则每完成一次握手就从FIFO读出grant知道下次要交互的Master,这样就实现了AW通道和W通道的流水啦。

既然两个通道使用同步FIFO隔离,那么就可以分成两个模块了

在这里插入图片描述

2.1. axi_round_robin_arbiter_aw

AW通道仲裁比较好说,但还是要使用状态机,此处的状态就要改成FIFO是否满了,FIFO满了通信就要阻断。

代码

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

对于W通道而言,必须从FIFO读出grant才能与grant规定的Master握手,所以还是按照状态机的设计过程,分为两个状态

在这里插入图片描述

RD_GRANT

该状态下就一直读FIFO,同时W通道被阻塞,直到grant被读出

在这里插入图片描述

HANDSHAKE

此时grant会一直保持,按照grant选择Master等待握手完成就可以。

在这里插入图片描述

代码

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丶]所创,转载请带上原文链接,感谢
https://blog.csdn.net/Starry__/article/details/125417003