电力电子转战数字IC20220611day22——SV实验MCDF

该博客主要介绍了基于Verilog的多通道数据传输系统,包括通道端的FIFO模块、仲裁器模块以及整个系统的顶层模块。FIFO模块实现了数据的缓存和读写控制,当FIFO不满时允许数据进入,并在满时禁止写入。仲裁器模块使用轮询仲裁策略,根据通道请求的优先级决定数据的输出。顶层模块连接了多个FIFO和仲裁器,处理来自不同通道的数据。在测试环境中,通过动态数组生成数据并进行传输验证。
摘要由CSDN通过智能技术生成

目录

SV DAY6

实验0代码解读 

通道端slave和FIFO的代码 

arbiter部分

MCDT代码

tb

实验1

tb2

任务task

tb3

 tb4


SV DAY6

未完成:

实验0代码解读 

其实实验0是没有formater这一部分的

 

通道端slave和FIFO的代码 

//
module slave_fifo (
input                       clk_i,                  // Clock input 
input                       rstn_i,                 // Reset signal 

input [31:0]             chx_data_i,             // 通道数据输入---->From outside
input                    a2sx_ack_i,             // Read ack     ---->From Arbiter
input                    chx_valid_i,            // 通道数据高位有效--->From Outside

output reg [31:0]        slvx_data_o,            // Data Output  ---->To Arbiter
output [5:0]             slvx_margin_o,          // Data margin  ---->To Outside
output reg               chx_ready_o,            // Ready to accept data--->To outside
output reg               slvx_val_o,             // Output data is valid--->To Arbiter
output reg               slvx_req_o              // Request to send date--->To Arbiter
);    
 
//声明内部变量,FIFO需要用到指针//
reg [5:0] wr_pointer_r;
reg [5:0] rd_pointer_r;
reg [31:0] mem [0:31]; //FIFO宽度32深度32

//声明net类型的变量,分别是FIFO满了,空了,可以读的信号,还有数据空间裕量//
wire full_s, empty_s, rd_en_s ;
wire [5:0] data_cnt_s;

//同步FIFO空满的标志,指针完全相同则为空,最高位相反其他位相同则为满//
assign full_s = ({~wr_pointer_r[5],wr_pointer_r[4:0]}==rd_pointer_r);
assign empty_s = (wr_pointer_r == rd_pointer_r);

//cnt用来计算FIFO还有多少空间?
assign data_cnt_s = (6'd32 - (wr_pointer_r - rd_pointer_r));
assign slvx_margin_o = data_cnt_s;

assign rd_en_s = a2sx_ack_i;



//如果不满,ready信号置1,表示可以进来数据//
always @ (*) //ready signal
begin
if (!full_s) chx_ready_o = 1'b1; 
else chx_ready_o = 1'b0;
end

//如果不空,req信号置1,表示可以发送数据,和上面可以同时出现//
always @ (*) //reset signal
begin 
  if (!rstn_i) slvx_req_o = 1'b0;
  else if (!empty_s) slvx_req_o = 1'b1;    
  else slvx_req_o = 1'b0;
end 

//写指针的定义,由于是同步FIFO,不用跨时钟域转换格雷码
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

//读指针
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
    rd_pointer_r <= rd_pointer_r + 6'b0001;
  end
end

//若无复位信号,且read使能信号高位,FIFO不空,则valid信号置1,表示可以输出(读)数据
always @ (posedge clk_i or negedge rstn_i)
begin
  if (!rstn_i) slvx_val_o <= 1'b0;
  else if (rd_en_s && (!empty_s))
    slvx_val_o <= 1'b1;
    else slvx_val_o <= 1'b0;
end 

// 将mem中的数据给到输出 
always  @ (posedge clk_i )
begin : READ_DATA 
  if (rstn_i && rd_en_s && (!empty_s)) begin
    slvx_data_o <= mem[rd_pointer_r[4:0]];
  end
end

// 将外部输入数据写给mem
always @ (posedge clk_i)
begin : MEM_WRITE
	if (rstn_i && chx_valid_i && chx_ready_o) begin
	  mem[wr_pointer_r[4:0]] <= chx_data_i;
	 end
end

endmodule 

arbiter部分

//需要用到clk和rst就要继续声明,变量名保持一致即可。//
module arbiter(
input                    clk_i,
input                    rstn_i,

//输入端是来自上一个module slv_fifo读出来的数据,三个通道分别是012.包括数据,req,valid总共3*3个//
input  [31:0]            slv0_data_i,
input  [31:0]            slv1_data_i,
input  [31:0]            slv2_data_i,
input                    slv0_req_i,
input                    slv1_req_i,
input                    slv2_req_i,
input                    slv0_val_i,
input                    slv1_val_i,
input                    slv2_val_i,

//a2si_ack_0是assign给rd_en_s的,也就是告诉3个FIFO谁可以读出数据给到arb
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值