仿真测试一个2路、4路IQ数据转成字节流的模块

66 篇文章 22 订阅
58 篇文章 27 订阅

代码前几天写好的,今天打算上VIVADO实际试验了,觉得没仿真不踏实,就仿真一把。

模块代码如下:将4路(可以通过使能控制是使用2路)的12位从AD9361采集到的原始数据转换成字节流(用以发送给后续的FPGA实现的千兆以太网)。


module IQ2FIFO(
input clk,rst,

input en,a_valid,b_valid,
input [11:0] d0,d1,d2,d3,
output reg rd_ab_io,

input wr_full, // when first full ,it can allow at least 16 items
output reg  wr_fifo,
output reg [7:0] wr_data 
);

wire access_ok  = en & ~wr_full ;
wire a_or_b_valid = a_valid | b_valid ;
reg [7:0] b5,b4,b3,b2,b1,b0 ;
wire [7:0] b5w,b4w,b3w,b2w,b1w,b0w ;
reg[7:0] st,str; always @(posedge clk)  str <= st ;

always @(posedge clk) if (str == 10)  { b5,b4,b3, b2,b1,b0} <= { d3 , d2 , d1 , d0 };
assign   { b5w,b4w,b3w,b2w,b1w,b0w } = { d3 , d2 , d1 , d0 }; 

always @ (posedge clk) if (rst)  st<=0; else 
case (st) 0:st<=10;
10: case ({access_ok,a_valid,b_valid}) 
3'b110 :st<=20;
3'b101 :st<=30;
3'b111 :st<=40;  
endcase 

20: st<=21;  // save byte1    b5 
21: st<=10;  // save byte2    b4
// save byte3 when str ==21   b3

30: st<=31;  // save byte1    b2
31: st<=10;  // save byte2    b1
//  save byte3  when st==10 check str==31    b0

40:st<=41; // byte 1 b5 
41:st<=42; // byte 2 b4
42:st<=43; // byte 3 b3
43:st<=44; // byte 4 b2
44:st<=10; // byte 5 b1
// save byte6 when str==44  b0 

default st<=0;
endcase 

always @(*)rd_ab_io = ( st==10 & access_ok &  ( a_valid | b_valid ) ) ;
always @(posedge clk)  case (st)
20,21,30,31,40,41,42,43,44:wr_fifo <= 1;
default wr_fifo <= (str==21) ||(str==31) ||(str==44) ;endcase 

always@(posedge clk)  case (st)
20:wr_data <=b5w;
21:wr_data <=b4;

30:wr_data <=b2w;
31:wr_data <=b1;

40:wr_data <=b5w;
41:wr_data <=b4;
42:wr_data <=b3;
43:wr_data <=b2;
44:wr_data <=b1;
default case (str)21:wr_data<=b3;31,44:wr_data<=b0;endcase 
endcase 

endmodule 


例化一下模块上来就写测试代码:

module iq2fifo_tb ;
 
reg clk=0,rst=0,en=0,a_valid=1,b_valid=1;

always#5 clk <= ~clk ;

 

initial begin 
$dumpfile ("a.vcd") ;
$dumpvars (0, iq2fifo_tb) ;  
end 

initial begin 
rst = 0 ;
#10; rst = 1 ;
#20; rst = 0 ; 

@(posedge clk);
//f=0;
a_valid=1; b_valid=0; en=1; 
#10000;//f = 1 ;
@(posedge clk);
a_valid=0; b_valid=1; en=1; 
#10000;//f = 2 ;

@(posedge clk);
a_valid=1; b_valid=1; en=1; 
#10000;//f = 2 ;

@(posedge clk);
$finish ;

end

wire [47:0]d3210_0 = {12'h333,12'h222,12'h111,12'h000} ;
wire [47:0]d3210_1 = {12'h444,12'h333,12'h222,12'h111} ;
wire [47:0]d3210_2 = {12'h555,12'h444,12'h333,12'h222} ;
wire [47:0]d3210_3 = {12'h666,12'h555,12'h444,12'h333} ; 


reg [1:0] idx = 0; always @(posedge clk ) if(rd_ab_io)idx<=idx+1 ;

reg [11:0] d0,d1,d2,d3; 
always @ (posedge clk) case (idx) 
0: {d3,d2,d1,d0} <= d3210_0 ;
1: {d3,d2,d1,d0} <= d3210_1 ;
2: {d3,d2,d1,d0} <= d3210_2 ;
3: {d3,d2,d1,d0} <= d3210_3 ;
endcase 

wire rd_ab_io ;
wire [7:0]  wr_data ;


IQ2FIFO IQ2FIFO(
.clk( clk ),
.rst( rst ),
.en( en ),
.a_valid( a_valid ),
.b_valid( b_valid),
.d0( d0 ),
.d1( d1 ),
.d2( d2 ),
.d3( d3 ),
.rd_ab_io( rd_ab_io ),
.wr_full( 1'b0 ), // when first full ,it can allow at least 16 items
.wr_fifo( wr_fifo ),
.wr_data ( wr_data )
);

endmodule 

在icarvous verilog下面仿真。

 上图可以看到在两个有效情况下输出正确。并且IO段每三个周期取一个数据,正好是每次取三个字节,没有浪费周期。

 上图可以看到在两个有效情况下输出正确。并且IQ每6个周期取一个数据,正好是每次取6个字节(12X4=48位),没有浪费周期。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值