mcdf的硬件verilog代码一、slave_fifo(包含部分注释)

1 篇文章 0 订阅
1 篇文章 0 订阅

 


前言

MCDF,全名多通道数据整形器(Multiple channels data formatter),他的功能是对多个channel的输入数据包,经由arbiter根据各个通道优先级仲裁,选定通道,并将数据交给formatter打包,一并输出的器件。每个channel的状态由一个32位的读写控制寄存器和一个32位的只读状态寄存器决定。

一、slave_fifo功能解析与实现步骤

slave端完成了一个外部数据输入的接受和认证,并将它们有序存放进FIFO中的功能,对来自arbiter的某些信号a2sx_ack_i做处理,arbiter从slave取完数据后,返回一个应答信号使得slave可以被再次读取。

二、slave_fifo.v

代码如下:

 

module slave_fifo (
//雷打不动的时钟与复位
input                       clk_i,                  // Clock input 
input                       rstn_i,                 // low level effective 
//外部输入的channnel数据32位
input [31:0]                chx_data_i,             // Data input                 ---->From outside
//从arbiter to slave的读ack???
input                       a2sx_ack_i,             // Read ack                   ---->From Arbiter
//通道使能
input                       slvx_en_i,              // Write enable To Registers  ---->To Register
//由外部而来,valid拉高,32位的数据写入才有效
input                       chx_valid_i,            // Data is valid From outside ---->From Outside
//slave通道输出数据,送往FIFOx???
output reg [31:0]           slvx_data_o,            // Data Output                ---->To Arbiter
//数据边界,即距离FIFO满还有多少
output [5:0]                margin_o,               // Data margin                ---->To Registers
//输出的ready,表明当前通道是否准备好接收数据,和FIFO的空满状态有关,满则ready拉低
output reg                  chx_ready_o,            // Ready to accept data       ---->To outside
//salve的输出数据的valid,表明输出数据的有效性
output reg                  slvx_val_o,             // read acknowledge Keep to handshake with Arbiter ----> To Arbiter
//slave的输出请求???
output reg                  slvx_req_o 
);     
//------------------------------Internal variables-------------------//
reg [5:0] wr_pointer_r;//FIFO的写指针
reg [5:0] rd_pointer_r;//FIFO的读指针
reg [31:0] mem [0:31]; //FIFO 32bits width and 32 deepth
//-----------------------------Variable assignments------------------//
wire full_s, empty_s, rd_en_s ;//定义了fifo满信号,空信号与读使能信号
wire [5:0] data_cnt_s;//计算FIFO余量
assign full_s = ({~wr_pointer_r[5],wr_pointer_r[4:0]}==rd_pointer_r);//满标志位用读写指针最高位相反,其余各位保持一致表示,这是fifo的一个特点
assign empty_s = (wr_pointer_r == rd_pointer_r);//空标志位用读指针与写指针相同表示
assign data_cnt_s = (6'd32 - (wr_pointer_r - rd_pointer_r));//fifo空状态能存6'd32个数据,减去写指针与读指针的差值,得到当前余量,这说明写指针是大于读指针的,fifo的一个特点就是只有两个指针,所以不能像存储器那样任意访问存储位置,只能先写再读
assign margin_o = data_cnt_s;//把余量大小输出
assign rd_en_s = a2sx_ack_i;//arbiter to slave的ack来了之后,说明可以开始读使能了???

//-----------Code Start---------------------------------------------//
//下列always块都是并行触发
//如果FIFO没满并且通道使能,那么ready拉高,可以接收数据
always @ (*) //ready signal
begin
if (!full_s && slvx_en_i) chx_ready_o = 1'b1;//If FIFO is not full and also enabled it is ready to accept data
else chx_ready_o = 1'b0;
end

//复位信号
always @ (*) //reset signal
begin 
  if (!rstn_i) slvx_req_o = 1'b0;//清零复位
  else if (!empty_s) slvx_req_o = 1'b1;//如果fifo非空,slave输出请求置1,可以输出数据
  else slvx_req_o = 1'b0;
end 

//write pointer increment
//写指针逻辑
always @ (posedge clk_i or negedge rstn_i)//敏感事件是每次时钟的上升沿或复位信号下降沿
begin : WRITE_POINTER
  if (!rstn_i) begin
    wr_pointer_r <= 6'b0000;//写指针复位
  end else 
  if (chx_valid_i && chx_ready_o) begin//输入数据有效且当前通道可以接受
    wr_pointer_r <= wr_pointer_r + 6'b0001;//每进行一次操作后指针地址加一
  end
end

//read pointer increment
//读指针逻辑
always @ (posedge clk_i or negedge rstn_i)
//敏感事件是每次时钟的上升沿或复位信号下降沿
begin : READ_POINTER
  if (!rstn_i) begin
    rd_pointer_r <= 6'b0000;//
  end else 
  if (rd_en_s && (!empty_s)) begin//读信号使能且FIFO非空
    rd_pointer_r <= rd_pointer_r + 6'b0001;//每进行一次操作后指针地址加一
  end
end

//data output is vaild 
//数据输出valid
always @ (posedge clk_i or negedge rstn_i)
//敏感事件是每次时钟的上升沿或复位信号下降沿
begin
  if (!rstn_i) slvx_val_o <= 1'b0;//slave的valid输出复位
  else if (rd_en_s && (!empty_s))//读信号使能且FIFO非空
    slvx_val_o <= 1'b1;//slave的valid输出置1,输出数据主动方认为有效
    else slvx_val_o <= 1'b0;//否则无效
end 

// Memory Read Block 
//读FIFO逻辑
always  @ (posedge clk_i )
//敏感事件仅取决于时钟上升沿
begin : READ_DATA 
  if (rstn_i && rd_en_s && (!empty_s)) begin//没按下复位,读信号使能且FIFO非空
    slvx_data_o <= mem[rd_pointer_r[4:0]];//slave端的数据输出从mem数组中取出读指针地址对应的32位数据,这里mem数据就是FIFO
  end
end

// Memory Write Block 
//写FIFO逻辑
always @ (posedge clk_i)
//敏感事件仅取决于时钟上升沿
begin : MEM_WRITE
	if (rstn_i && chx_valid_i && chx_ready_o && slvx_en_i) begin//没复位,通道输入数据主动方认为有效,通道准备好,slave使能
	  mem[wr_pointer_r[4:0]] <= chx_data_i;//把外部输入数据写入FIFO对应写指针的地址内
	 end
end

endmodule 


//slave端完成了一个外部数据输入的接受和认证,并将它们有序存放进FIFO中的功能,对来自arbiter的某些信号a2sx_ack_i做处理,arbiter从slave取完数据后,返回一个应答信号使得slave可以被再次读取

  • 2
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值