DDR3  IP基础知识  (1条消息) 快速上手Xilinx DDR3 IP核----汇总篇(MIG)_ddr3 xilinx_孤独的单刀的博客-CSDN博客

DDR3 tb文件

  1 `timescale 1ns / 1ps
  2 //////////////////////////////////////////////////////////////////////////////////
  3 // Company: 
  4 // Engineer: 
  5 // 
  6 // Create Date: 2022/08/17 10:52:08
  7 // Design Name: 
  8 // Module Name: tb
  9 // Project Name: 
 10 // Target Devices: 
 11 // Tool Versions: 
 12 // Description: 
 13 // 
 14 // Dependencies: 
 15 // 
 16 // Revision:
 17 // Revision 0.01 - File Created
 18 // Additional Comments:
 19 // 
 20 //////////////////////////////////////////////////////////////////////////////////
 21 
 22 
 23 module axi4_mig_tb;
 24 
 25 reg                clk_100M            ;
 26 reg                clk_200M            ;
 27 reg                rst_n                ;
 28 
 29 wire    [3:0]    M00_AXI_awid        ;
 30 wire    [31:0]    M00_AXI_awaddr        ;
 31 wire    [7:0]    M00_AXI_awlen        ;
 32 wire    [2:0]    M00_AXI_awsize        ;
 33 wire    [1:0]    M00_AXI_awburst        ;
 34 wire            M00_AXI_awlock        ;
 35 wire    [3:0]    M00_AXI_awcache        ;
 36 wire    [2:0]    M00_AXI_awprot        ;
 37 wire    [3:0]    M00_AXI_awqos        ;
 38 wire            M00_AXI_awvalid        ;
 39 wire            M00_AXI_awready        ;
 40 wire    [63:0]    M00_AXI_wdata        ;
 41 wire    [7:0]    M00_AXI_wstrb        ;
 42 wire            M00_AXI_wlast        ;
 43 wire            M00_AXI_wvalid        ;
 44 wire            M00_AXI_wready        ;
 45 wire    [3:0]    M00_AXI_bid            ;
 46 wire    [1:0]    M00_AXI_bresp        ;
 47 wire            M00_AXI_bvalid        ;
 48 wire            M00_AXI_bready        ;
 49 wire    [3:0]    M00_AXI_arid        ;
 50 wire    [31:0]    M00_AXI_araddr        ;
 51 wire    [7:0]     M00_AXI_arlen        ;
 52 wire    [2:0]     M00_AXI_arsize        ;
 53 wire    [1:0]     M00_AXI_arburst        ;
 54 wire            M00_AXI_arlock        ;
 55 wire    [3:0]     M00_AXI_arcache        ;
 56 wire    [2:0]     M00_AXI_arprot        ;
 57 wire    [3:0]     M00_AXI_arqos        ;
 58 wire            M00_AXI_arvalid        ;
 59 wire            M00_AXI_arready        ;
 60 wire    [3:0]    M00_AXI_rid            ;
 61 wire    [63:0]    M00_AXI_rdata        ;
 62 wire    [1:0]    M00_AXI_rresp        ;
 63 wire            M00_AXI_rlast        ;
 64 wire            M00_AXI_rvalid        ;
 65 wire            M00_AXI_rready        ;
 66 
 67 wire            src_vs                ;            
 68 wire            src_de                ;
 69 wire    [7:0]    src_data            ;
 70         
 71 wire            mid_de                ;
 72 wire    [7:0]    mid_data            ;
 73 wire            mid_start            ;
 74 
 75 wire            dst_vs                ;
 76 wire            dst_de                ;
 77 wire    [7:0]    dst_data            ;
 78 wire    [31:0]     dst_cnt                ;
 79 wire               dst_end                ;
 80 
 81 wire            axi_rd_start        ;
 82 
 83 wire     [14:0]    ddr3_addr            ;
 84 wire     [2:0]    ddr3_ba             ;
 85 wire            ddr3_cas_n          ;
 86 wire     [0:0]    ddr3_ck_n           ;
 87 wire     [0:0]    ddr3_ck_p           ;
 88 wire     [0:0]    ddr3_cke            ;
 89 wire            ddr3_ras_n          ;
 90 wire            ddr3_reset_n        ;
 91 wire            ddr3_we_n           ;
 92 wire     [7:0]    ddr3_dq             ;
 93 wire     [0:0]    ddr3_dqs_n          ;
 94 wire     [0:0]    ddr3_dqs_p          ;
 95 wire     [0:0]    ddr3_cs_n           ;
 96 wire     [0:0]    ddr3_dm             ;
 97 wire     [0:0]    ddr3_odt            ;
 98 
 99 wire            init_done            ;
100 
101 wire            ui_clk                ;
102 wire            ui_rst                ;
103 
104 integer    outfile;
105 
106 initial begin
107     clk_100M    =  0;
108     clk_200M    =  0;
109     rst_n        =  0;
110 
111     #11
112     
113     rst_n        =  1;
114     
115     #100
116 
117     outfile = $fopen("H:/xilinx2019/secondlevel/study/vip/lesson11/data/post.txt","w");
118 end
119 
120 always #5   clk_100M = ~clk_100M;
121 always #2.5 clk_200M = ~clk_200M;
122 
123 localparam S_IW    = 32  ;
124 localparam S_IH = 32  ;
125 
126 img_gen #(
127     .ACTIVE_IW    (S_IW        ),
128     .ACTIVE_IH    (S_IH        ),
129     .TOTAL_IW     (S_IW + 200    ),
130     .TOTAL_IH     (S_IH + 200    ),
131     .H_START      (5            ),
132     .V_START      (5            ) 
133 )
134 u0_img_gen
135 ( 
136     .clk        (clk_100M    ),
137     .rst_n        (rst_n        ), 
138     .vs            (src_vs        ), 
139     .de            (src_de        ),
140     .data        (src_data    ),
141     
142     .wr_start    (init_done    ), //DDR初始化完成
143     .rd_start   (axi_rd_start) //输出十行数据
144 );
145 
146 axi_dma #(
147     .AXI_ADDR_WIDTH    (32                ),
148     .AXI_BUF_SIZE    (1                ),
149     .AXI_ADDR_BASE    (32'h00000000    ),
150 
151     .WR_CH_EN        (1                ),
152     .WR_BURST_LEN    (4                ), 
153     .WR_DATA_WIDTH    (64                ),
154     .WR_IW            (32                ),
155     .WR_IH            (32                ),
156 
157     .RD_CH_EN        (1                ),
158     .RD_BURST_LEN    (4               ),
159     .RD_DATA_WIDTH    (64                ),
160     .RD_IW            (32              ),
161     .RD_IH            (32              ),
162     
163     .I_DW             (8                ),
164     .O_DW             (8                )     
165 )
166 u0_axi_dma
167 (
168 //user_wr    
169     .pre_clk                (clk_100M            ),
170     .pre_vs                    (src_vs                ),
171     .pre_de                    (src_de                ),
172     .pre_data                (src_data            ),
173 //user_rd                         
174     .post_clk                (clk_100M            ),
175     .post_de                (mid_de                ),
176     .post_data                (mid_data            ),    
177     .post_start                (mid_start            ),//读FIFO中满足要求,开始读取数据
178 //ex_signal    
179     .o_wr_index                (                    ),
180 //in_signal    
181     .axi_rd_start            (axi_rd_start        ), //信号输入端输出10行数据,开始拉高读开始信号
182     .i_wr_index                (8'd1                ),
183 //axi_logic        
184     .M_AXI_ACLK                (ui_clk                ),                                    
185     .M_AXI_ARESETN            (~ui_rst            ),                                 
186     .M_AXI_AWID                (M00_AXI_awid        ),                
187     .M_AXI_AWADDR            (M00_AXI_awaddr        ),                  
188     .M_AXI_AWLEN            (M00_AXI_awlen        ),                            
189     .M_AXI_AWSIZE            (M00_AXI_awsize        ),                            
190     .M_AXI_AWBURST            (M00_AXI_awburst    ),                        
191     .M_AXI_AWLOCK            (M00_AXI_awlock        ),                            
192     .M_AXI_AWCACHE            (M00_AXI_awcache    ),                        
193     .M_AXI_AWPROT            (M00_AXI_awprot        ),                            
194     .M_AXI_AWQOS            (M00_AXI_awqos        ),                            
195     .M_AXI_AWVALID            (M00_AXI_awvalid    ),                        
196     .M_AXI_AWREADY            (M00_AXI_awready    ),                        
197     .M_AXI_WDATA            (M00_AXI_wdata        ),                              
198     .M_AXI_WSTRB            (M00_AXI_wstrb        ),                              
199     .M_AXI_WLAST            (M00_AXI_wlast        ),                               
200     .M_AXI_WVALID            (M00_AXI_wvalid        ),                              
201     .M_AXI_WREADY            (M00_AXI_wready        ),                              
202     .M_AXI_BID                (M00_AXI_bid        ),                          
203     .M_AXI_BRESP            (M00_AXI_bresp        ),                              
204     .M_AXI_BVALID            (M00_AXI_bvalid        ),                              
205     .M_AXI_BREADY            (M00_AXI_bready        ),                             
206     .M_AXI_ARID                (M00_AXI_arid        ),                          
207     .M_AXI_ARADDR            (M00_AXI_araddr        ),                               
208     .M_AXI_ARLEN            (M00_AXI_arlen        ),                              
209     .M_AXI_ARSIZE            (M00_AXI_arsize        ),                              
210     .M_AXI_ARBURST            (M00_AXI_arburst    ),                          
211     .M_AXI_ARLOCK            (M00_AXI_arlock        ),                              
212     .M_AXI_ARCACHE            (M00_AXI_arcache    ),                          
213     .M_AXI_ARPROT            (M00_AXI_arprot        ),                              
214     .M_AXI_ARQOS            (M00_AXI_arqos        ),                                
215     .M_AXI_ARVALID            (M00_AXI_arvalid    ),                          
216     .M_AXI_ARREADY            (M00_AXI_arready    ),                          
217     .M_AXI_RID                (M00_AXI_rid        ),                          
218     .M_AXI_RDATA            (M00_AXI_rdata        ),                              
219     .M_AXI_RRESP            (M00_AXI_rresp        ),                              
220     .M_AXI_RLAST            (M00_AXI_rlast        ),                              
221     .M_AXI_RVALID            (M00_AXI_rvalid        ),                            
222     .M_AXI_RREADY            (M00_AXI_rready        )                              
223 );                                             
224 
225 mig_7series_0 u_mig_7series_0 (
226     // Memory interface ports
227     .ddr3_addr                      (ddr3_addr        ),  // output [14:0]    ddr3_addr
228     .ddr3_ba                        (ddr3_ba        ),  // output [2:0]        ddr3_ba
229     .ddr3_cas_n                     (ddr3_cas_n        ),  // output            ddr3_cas_n
230     .ddr3_ck_n                      (ddr3_ck_n        ),  // output [0:0]        ddr3_ck_n
231     .ddr3_ck_p                      (ddr3_ck_p        ),  // output [0:0]        ddr3_ck_p
232     .ddr3_cke                       (ddr3_cke        ),  // output [0:0]        ddr3_cke
233     .ddr3_ras_n                     (ddr3_ras_n        ),  // output            ddr3_ras_n
234     .ddr3_reset_n                   (ddr3_reset_n    ),  // output            ddr3_reset_n
235     .ddr3_we_n                      (ddr3_we_n        ),  // output            ddr3_we_n
236     .ddr3_dq                        (ddr3_dq        ),  // inout [7:0]        ddr3_dq
237     .ddr3_dqs_n                     (ddr3_dqs_n        ),  // inout [0:0]        ddr3_dqs_n
238     .ddr3_dqs_p                     (ddr3_dqs_p        ),  // inout [0:0]        ddr3_dqs_p
239     
240     .init_calib_complete            (init_done        ),  // output            init_calib_complete
241     
242     .ddr3_cs_n                      (ddr3_cs_n        ),  // output [0:0]        ddr3_cs_n
243     .ddr3_dm                        (ddr3_dm        ),  // output [0:0]        ddr3_dm
244     .ddr3_odt                       (ddr3_odt        ),  // output [0:0]        ddr3_odt
245     // Application interface ports 输入给0,输出悬空
246     .ui_clk                         (ui_clk            ),  // output            ui_clk
247     .ui_clk_sync_rst                (ui_rst            ),  // output            ui_clk_sync_rst
248     .mmcm_locked                    (                ),  // output            mmcm_locked
249     .aresetn                        (rst_n            ),  // input            aresetn
250     .app_sr_req                     (1'b0            ),  // input            app_sr_req
251     .app_ref_req                    (1'b0            ),  // input            app_ref_req
252     .app_zq_req                     (1'b0            ),  // input            app_zq_req
253     .app_sr_active                  (                 ),  // output            app_sr_active
254     .app_ref_ack                    (                 ),  // output            app_ref_ack
255     .app_zq_ack                     (                 ),  // output            app_zq_ack
256     // Slave Interface Write Address Ports
257     .s_axi_awid                     (M00_AXI_awid    ),  // input [3:0]        s_axi_awid
258     .s_axi_awaddr                   (M00_AXI_awaddr    ),  // input [27:0]        s_axi_awaddr
259     .s_axi_awlen                    (M00_AXI_awlen    ),  // input [7:0]        s_axi_awlen
260     .s_axi_awsize                   (M00_AXI_awsize    ),  // input [2:0]        s_axi_awsize
261     .s_axi_awburst                  (M00_AXI_awburst),  // input [1:0]        s_axi_awburst
262     .s_axi_awlock                   (M00_AXI_awlock    ),  // input [0:0]        s_axi_awlock
263     .s_axi_awcache                  (M00_AXI_awcache),  // input [3:0]        s_axi_awcache
264     .s_axi_awprot                   (M00_AXI_awprot    ),  // input [2:0]        s_axi_awprot
265     .s_axi_awqos                    (M00_AXI_awqos    ),  // input [3:0]        s_axi_awqos
266     .s_axi_awvalid                  (M00_AXI_awvalid),  // input            s_axi_awvalid
267     .s_axi_awready                  (M00_AXI_awready),  // output            s_axi_awready
268     // Slave Interface Write Data Ports
269     .s_axi_wdata                    (M00_AXI_wdata    ),  // input [63:0]        s_axi_wdata
270     .s_axi_wstrb                    (M00_AXI_wstrb    ),  // input [7:0]        s_axi_wstrb
271     .s_axi_wlast                    (M00_AXI_wlast    ),  // input            s_axi_wlast
272     .s_axi_wvalid                   (M00_AXI_wvalid    ),  // input            s_axi_wvalid
273     .s_axi_wready                   (M00_AXI_wready    ),  // output            s_axi_wready
274     // Slave Interface Write Response Ports
275     .s_axi_bid                      (M00_AXI_bid    ),  // output [3:0]        s_axi_bid
276     .s_axi_bresp                    (M00_AXI_bresp    ),  // output [1:0]        s_axi_bresp
277     .s_axi_bvalid                   (M00_AXI_bvalid    ),  // output            s_axi_bvalid
278     .s_axi_bready                   (M00_AXI_bready    ),  // input            s_axi_bready
279     // Slave Interface Read Address Ports
280     .s_axi_arid                     (M00_AXI_arid    ),  // input [3:0]        s_axi_arid
281     .s_axi_araddr                   (M00_AXI_araddr    ),  // input [27:0]        s_axi_araddr
282     .s_axi_arlen                    (M00_AXI_arlen    ),  // input [7:0]        s_axi_arlen
283     .s_axi_arsize                   (M00_AXI_arsize    ),  // input [2:0]        s_axi_arsize
284     .s_axi_arburst                  (M00_AXI_arburst),  // input [1:0]        s_axi_arburst
285     .s_axi_arlock                   (M00_AXI_arlock    ),  // input [0:0]        s_axi_arlock
286     .s_axi_arcache                  (M00_AXI_arcache),  // input [3:0]        s_axi_arcache
287     .s_axi_arprot                   (M00_AXI_arprot    ),  // input [2:0]        s_axi_arprot
288     .s_axi_arqos                    (M00_AXI_arqos    ),  // input [3:0]        s_axi_arqos
289     .s_axi_arvalid                  (M00_AXI_arvalid),  // input            s_axi_arvalid
290     .s_axi_arready                  (M00_AXI_arready),  // output            s_axi_arready
291     // Slave Interface Read Data Ports
292     .s_axi_rid                      (M00_AXI_rid    ),  // output [3:0]        s_axi_rid
293     .s_axi_rdata                    (M00_AXI_rdata    ),  // output [63:0]    s_axi_rdata
294     .s_axi_rresp                    (M00_AXI_rresp    ),  // output [1:0]        s_axi_rresp
295     .s_axi_rlast                    (M00_AXI_rlast    ),  // output            s_axi_rlast
296     .s_axi_rvalid                   (M00_AXI_rvalid    ),  // output            s_axi_rvalid
297     .s_axi_rready                   (M00_AXI_rready    ),  // input            s_axi_rready
298     // System Clock Ports
299     .sys_clk_i                      (clk_200M        ),//通过PLL输出给MIG作为系统时钟和参考时钟用
300     .sys_rst                        (rst_n            ) // input sys_rst
301 );
302 
303 ddr3_model u_ddr3_model(
304     .rst_n                  (ddr3_reset_n        ),
305     .ck                     (ddr3_ck_p            ),
306     .ck_n                   (ddr3_ck_n            ),
307     .cke                    (ddr3_cke            ),
308     .cs_n                   (ddr3_cs_n            ),
309     .ras_n                  (ddr3_ras_n            ),
310     .cas_n                  (ddr3_cas_n            ),
311     .we_n                   (ddr3_we_n            ),
312     .dm_tdqs                (ddr3_dm            ),
313     .ba                     (ddr3_ba            ),
314     .addr                   (ddr3_addr            ),
315     .dq                     (ddr3_dq            ),
316     .dqs                    (ddr3_dqs_p            ),
317     .dqs_n                  (ddr3_dqs_n            ),
318     .tdqs_n                 (                    ),
319     .odt                    (ddr3_odt            )
320 );
321 
322 img_rd #(
323     .S_IW (S_IW),
324     .S_IH (S_IH)
325 )
326 u1_img_rd
327 (
328     .clk_100M                (clk_100M            ),
329     .rst_n                    (rst_n                ),
330         
331     .mid_de                    (mid_de                ),    
332     .mid_data                (mid_data            ),
333     .mid_start                (mid_start            ),
334             
335     .dst_vs                    (dst_vs                ),
336     .dst_de                    (dst_de                ),
337     .dst_data                (dst_data            ),
338     .dst_cnt                (dst_cnt            ),
339     .dst_end                (dst_end            )    
340 );                                                
341 
342 always @(posedge clk_100M or negedge rst_n)
343     if(dst_de==1)
344         begin
345             $fdisplay(outfile,"%h",dst_data);
346         end 
347 
348 always @(posedge clk_100M or negedge rst_n)
349     if(dst_end)
350         begin
351             $stop;
352         end
353 
354     
355 endmodule

对于 ID参数,直接给0,因为AXI_interconnect会自己分配ID,写FIFO复位的时候,需要多拉高几个周期的复位信号,因为对于时钟速率相差较大的两个读写时钟,如果复位信号只是一个周期,会导致写FIFO一直存于复位状态

对于axi_wlast信号,不能直接使用组合逻辑,因为可能会导致在mig ip核中出错,

 

  1 module axi_dma #(
  2     parameter     AXI_ADDR_WIDTH    = 32            ,       //AXI地址位宽
  3     parameter     AXI_BUF_SIZE    = 3                ,       //BUF个数
  4     parameter   AXI_ADDR_BASE    = 32'h00000000    ,        //基地址
  5 
  6     parameter    WR_CH_EN        = 1                ,       //写通道使能
  7     parameter     WR_BURST_LEN    = 80            ,       //写突发长度
  8     parameter     WR_DATA_WIDTH    = 64            ,       //写数据位宽
  9     parameter     WR_IW            = 640            ,       //输入图像行像素宽度
 10     parameter     WR_IH            = 512            ,       //输入图像场像素高度
 11 
 12     parameter    RD_CH_EN        = 1                ,
 13     parameter    RD_BURST_LEN    = 80            ,
 14     parameter     RD_DATA_WIDTH    = 64            ,
 15     parameter    RD_IW            = 640           ,
 16     parameter    RD_IH            = 512           ,
 17     
 18     parameter   I_DW             = 8                ,       //输入像素位宽
 19     parameter   O_DW             = 8                        //输出像素位宽
 20 )
 21 (
 22 
 23     input    wire                                pre_clk                ,       //输入数据时钟信号
 24     input   wire                                pre_vs                ,       //输入场信号
 25     input    wire                                pre_de                ,       //数据有效信号
 26     input    wire    [I_DW-1:0]                    pre_data            ,       //输入数据
 27 
 28     input      wire                                post_clk            ,       //输出数据时钟
 29     input      wire                                post_de                ,       //输出数据使能
 30     output     wire    [O_DW-1:0]                    post_data            ,       //输出数据
 31     output     reg                                     post_start            ,       //数据可读信号,拉高后一直保持
 32     
 33     input    wire                                axi_rd_start        ,       //外围设备准备完毕信号
 34 
 35     input    wire    [7:0]                        i_wr_index            ,        //写指示信号
 36     output    reg        [7:0]                        o_wr_index            ,       
 37 
 38     output    reg                                    wr_irq                ,       //一帧数据中断信号
 39     
 40     input     wire                                  M_AXI_ACLK            ,       //AXI 时钟
 41     input     wire                                  M_AXI_ARESETN        ,       //AXI 复位
 42     output     wire                                 M_AXI_AWID            ,        //AXI 写地址ID
 43     output     wire    [AXI_ADDR_WIDTH-1:0]         M_AXI_AWADDR        ,       //AXI 写地址
 44     output     wire    [7:0]                        M_AXI_AWLEN            ,       //AXI 一次突发长度 M_AXI_AWLEN    = WR_BURST_LEN - 1'b1 (1-255)
 45     output     wire    [2:0]                        M_AXI_AWSIZE        ,       //AXI M_AXI_AWSIZE    = clogb2((WR_DATA_WIDTH/8)-1) = 3
 46     output     wire    [1:0]                         M_AXI_AWBURST        ,       //2'b01  地址递增模式
 47     output     wire                                  M_AXI_AWLOCK        ,       //1'b0
 48     output     wire    [3:0]                         M_AXI_AWCACHE        ,       //4'b0010 ,ACP接口给4'b0011
 49     output     wire    [2:0]                         M_AXI_AWPROT        ,       //3'b0
 50     output     wire    [3:0]                         M_AXI_AWQOS            ,       //4'b0
 51     output     wire                                  M_AXI_AWVALID        ,       
 52     input    wire                                  M_AXI_AWREADY        ,    
 53     output  wire    [WR_DATA_WIDTH-1:0]         M_AXI_WDATA            ,     
 54     output  wire     [WR_DATA_WIDTH/8-1:0]         M_AXI_WSTRB            ,        //数据掩码
 55     output  wire                                  M_AXI_WLAST            ,         //一次突发结束信号     
 56     output  wire                                  M_AXI_WVALID        ,     
 57     input   wire                                  M_AXI_WREADY        ,     
 58     input   wire                                  M_AXI_BID            ,        //响应ID
 59     input   wire     [1:0]                         M_AXI_BRESP            ,        
 60     input   wire                                  M_AXI_BVALID        ,    
 61     output  wire                                  M_AXI_BREADY        ,                                                                              
 62     output  wire                                  M_AXI_ARID            ,        //读地址ID
 63     output  wire     [AXI_ADDR_WIDTH-1:0]         M_AXI_ARADDR        ,         
 64     output  wire     [7:0]                         M_AXI_ARLEN            ,        //一次读突发长度
 65     output  wire     [2:0]                        M_AXI_ARSIZE        ,     
 66     output  wire     [1:0]                         M_AXI_ARBURST        ,        //2'b01 地址递增模式
 67     output  wire                                  M_AXI_ARLOCK        ,        //1‘b0
 68     output  wire     [3:0]                         M_AXI_ARCACHE        ,        //4'b0010
 69     output  wire     [2:0]                         M_AXI_ARPROT        ,        //3'b0
 70     output  wire     [3:0]                         M_AXI_ARQOS            ,          //4'b0
 71     output  wire                                  M_AXI_ARVALID        ,     
 72     input   wire                                  M_AXI_ARREADY        ,     
 73     input   wire                                  M_AXI_RID            ,     
 74     input   wire     [RD_DATA_WIDTH-1:0]         M_AXI_RDATA            ,     
 75     input   wire     [1:0]                         M_AXI_RRESP            ,     
 76     input   wire                                  M_AXI_RLAST            ,      
 77     input   wire                                  M_AXI_RVALID        ,    
 78     output  wire                                  M_AXI_RREADY             
 79 );
 80 
 81 localparam     addr_offset         =     WR_IW*WR_IH*I_DW/8                ;   //一帧数据的地址偏移
 82 
 83 localparam  wr_burst_bytes        =     WR_BURST_LEN*WR_DATA_WIDTH/8    ;   //写突发一次的字节数
 84 localparam  rd_burst_bytes        =     RD_BURST_LEN*RD_DATA_WIDTH/8    ;   //读突发一次的字节数
 85 
 86 localparam     wr_burst_times         =     WR_IW*WR_IH*I_DW/8/wr_burst_bytes        ;   //一帧数据突发的次数
 87 localparam     rd_burst_times         =     WR_IW*WR_IH*O_DW/8/rd_burst_bytes        ;   //一帧数据突发的次数
 88 
 89 //AXI_WR
 90 reg                                   pre_vs_r        ;
 91 wire                                 pre_pose        ;
 92 wire                                 pre_nege        ;
 93 wire                                ext_pre_pose    ;
 94 
 95 wire                                o_data_de         ;     
 96 wire    [WR_DATA_WIDTH-1:0]            o_data            ;
 97 
 98 wire                                sys_pre_nege    ;
 99 reg                                    sys_pre_nege_r    ;    
100 
101 reg        [7:0]                         wr_index        ;     
102 reg        [31:0]                        wr_base_addr    ;    
103 reg                                    wr_burst_start    ;    
104 reg                                    wr_cycle_flag    ;        
105         
106 reg                                  axi_awvalid        ;    
107 reg     [AXI_ADDR_WIDTH-1:0]         axi_awaddr        ;
108 reg                                  axi_wvalid        ;
109 wire     [WR_DATA_WIDTH-1:0]         axi_wdata        ;
110 reg                                  axi_wlast        ;
111 wire                                  axi_bready        ;
112 
113 reg        [7:0]                        burst_cnt        ;        
114 wire                                axi_wdata_de    ;    
115 
116 wire                                wr_full            ;
117 wire                                wr_empty        ;
118 wire    [10:0]                        wr_rd_data_count;
119 wire    [10:0]                        wr_wr_data_count;
120 
121 reg        [15:0]                      cnt_1us            ;
122         
123 always@(posedge pre_clk)
124     if(!M_AXI_ARESETN)
125         pre_vs_r <= 1'd0;
126     else 
127         pre_vs_r <= pre_vs;
128 
129 assign    pre_pose        = ~pre_vs_r&&pre_vs            ;
130 assign  pre_nege        = ~pre_vs&&pre_vs_r            ;
131 
132 data_sync_ext u1_data_sync_ext(
133     .clka            (pre_clk        ),
134     .rst_n            (M_AXI_ARESETN    ),    
135     .pulse_a        (pre_pose        ),
136     .ext_pulse_a    (ext_pre_pose    )
137 );
138 
139 
140 // ila_0 u3_ila_0 (
141     // .clk(pre_clk), // input wire clk
142 
143     // .probe0({
144     // pre_vs,
145     // pre_vs_r,
146     // pre_pose,
147     // pre_de,
148     // pre_data,
149     // o_data_de,
150     // o_data,
151     // ext_pre_pose
152     // }) // input wire [255:0] probe0
153 // );
154 
155 // ila_0 u4_ila_0 (
156     // .clk(M_AXI_ACLK), // input wire clk
157 
158     // .probe0({
159     // wr_burst_start,
160     // wr_cycle_flag,
161     // axi_awvalid,
162     // M_AXI_AWREADY,
163     // axi_awaddr,
164     // burst_cnt,
165     // axi_wlast,
166     // axi_wdata_de,
167     // axi_wdata,
168     // rd_index,
169     // wr_index,
170     // rd_flag,
171     // rd_cmd_flag,
172     // axi_arvalid,
173     // M_AXI_ARREADY,
174     // axi_araddr,
175     // rd_data_flag,
176     // axi_rready,
177     // axi_rdata_de,
178     // M_AXI_RDATA,
179     // axi_wvalid,
180     // M_AXI_WREADY,
181     // rd_wr_data_count,
182     // rd_rd_data_count,
183     // post_start,
184     // post_de,
185     // post_hcnt,
186     // post_vcnt,
187     // rd_hcnt,
188     // rd_vcnt
189     
190     
191     // }) // input wire [255:0] probe0
192 // );
193 
194 
195 
196 //数据拼接
197 data_joint #(
198     .IW_WIDTH        (I_DW              ),
199     .OW_WIDTH        (WR_DATA_WIDTH    )
200 )
201 u1_data_joint
202 (    
203     .clk            (pre_clk        ),
204     .rst_n            (~pre_pose&&M_AXI_ARESETN    ),
205     .i_data_de       (pre_de            ),
206     .i_data            (pre_data        ),
207     .o_data_de       (o_data_de      ),            
208     .o_data            (o_data            )
209 );        
210 //同步场下降沿信号
211 fifo_8_sys u1_fifo_fs_start
212 (
213     .wr_clk            (pre_clk        ), 
214     .rd_clk            (M_AXI_ACLK        ), 
215     .din            (8'd1            ), 
216     .wr_en            (pre_nege        ), 
217     .rd_en            (~sys_pre_nege    ), 
218     .dout            (                ), 
219     .full            (                ), 
220     .empty            (sys_pre_nege    )
221 );
222 
223 always@(posedge M_AXI_ACLK)
224     if(!M_AXI_ARESETN )    
225         sys_pre_nege_r <= 1'b0;
226     else
227         sys_pre_nege_r <= ~sys_pre_nege;
228     
229 always@(posedge M_AXI_ACLK)
230     if(!M_AXI_ARESETN)
231         wr_index <= 'd1;
232     else if(~sys_pre_nege==1'b1&&wr_index==AXI_BUF_SIZE[7:0])
233         wr_index <= 'd1;
234     else if(~sys_pre_nege==1'b1)
235         wr_index <= wr_index + 1'b1;
236     else
237         wr_index <= wr_index;
238 
239 always@(posedge M_AXI_ACLK)
240     if(!M_AXI_ARESETN)
241         o_wr_index <= 'd0;
242     else
243         o_wr_index <= wr_index;
244         
245 always@(posedge M_AXI_ACLK)
246     if(!M_AXI_ARESETN)
247         wr_base_addr <= 'd0;
248     else if(~sys_pre_nege==1'b1&&wr_index==AXI_BUF_SIZE[7:0])
249         wr_base_addr <= 'd0;
250     else if(~sys_pre_nege==1'b1)
251         wr_base_addr <= wr_base_addr + addr_offset;
252     else
253         wr_base_addr <= wr_base_addr;            
254 //发起突发开始信号        
255 always@(posedge M_AXI_ACLK)
256     if(!M_AXI_ARESETN)
257         wr_burst_start <= 1'b0;
258     else if(wr_rd_data_count>=WR_BURST_LEN&&WR_CH_EN[0]==1'b1)
259         wr_burst_start <= 1'b1;
260     else 
261         wr_burst_start <= 1'b0;              
262 //写周期标志
263 always@(posedge M_AXI_ACLK)
264     if(!M_AXI_ARESETN)
265         wr_cycle_flag <= 1'b0;
266     else if(wr_cycle_flag==1'b1&&axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&axi_wlast==1'b1)
267         wr_cycle_flag <= 1'b0;
268     else if(wr_burst_start==1'b1&&wr_cycle_flag==1'b0)
269         wr_cycle_flag <= 1'b1;                            
270     else
271         wr_cycle_flag <= wr_cycle_flag;
272 //写地址valid信号
273 always@(posedge M_AXI_ACLK)
274     if(!M_AXI_ARESETN)
275         axi_awvalid <= 1'b0;
276     else if(axi_awvalid==1'b1&&M_AXI_AWREADY==1'b1)
277         axi_awvalid <= 1'b0;
278     else if(wr_burst_start==1'b1&&wr_cycle_flag==1'b0)
279         axi_awvalid <= 1'b1;     
280     else
281         axi_awvalid <= axi_awvalid;
282     
283 always@(posedge M_AXI_ACLK)
284     if(!M_AXI_ARESETN)
285         axi_awaddr <= 'd0;
286     else if(sys_pre_nege_r==1'b1)
287         axi_awaddr <= wr_base_addr;
288     else if(axi_awvalid==1'b1&&M_AXI_AWREADY==1'b1)
289         axi_awaddr <= axi_awaddr + wr_burst_bytes ;
290     else
291         axi_awaddr <= axi_awaddr;
292 
293 always@(posedge M_AXI_ACLK)
294     if(!M_AXI_ARESETN)
295         axi_wvalid <= 1'b0;
296     else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&burst_cnt==WR_BURST_LEN-1)
297         axi_wvalid <= 1'b0;
298     else if(axi_awvalid==1'b1&&M_AXI_AWREADY==1'b1)
299         axi_wvalid <= 1'b1;
300     else
301         axi_wvalid <= axi_wvalid;
302     
303 always@(posedge M_AXI_ACLK)
304     if(!M_AXI_ARESETN)
305         burst_cnt <= 'd0;
306     else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&burst_cnt==WR_BURST_LEN-1)
307         burst_cnt <= 'd0;
308     else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1)
309         burst_cnt <= burst_cnt + 1'b1;            
310     else 
311         burst_cnt <= burst_cnt ;    
312     
313 always@(posedge M_AXI_ACLK)
314     if(!M_AXI_ARESETN)
315         axi_wlast <= 1'b0;
316     else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&burst_cnt==WR_BURST_LEN-1)
317         axi_wlast <= 1'b0;
318     else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&burst_cnt==WR_BURST_LEN-2) 
319         axi_wlast <= 1'b1;
320     else
321         axi_wlast <= axi_wlast;
322                     
323 assign axi_bready = 1'b1;
324         
325 assign axi_wdata_de = axi_wvalid&&M_AXI_WREADY;  
326 
327 always@(posedge M_AXI_ACLK)
328     if(!M_AXI_ARESETN)
329         wr_irq <= 1'b0;
330     else if(cnt_1us==99)
331         wr_irq <= 1'b0;
332     else if(~sys_pre_nege==1'b1)
333         wr_irq <= 1'b1;
334     else
335         wr_irq <= wr_irq;
336 
337 always@(posedge M_AXI_ACLK)
338     if(!M_AXI_ARESETN)
339         cnt_1us <= 'd0;
340     else if(cnt_1us==99)
341         cnt_1us <= 'd0;
342     else if(wr_irq==1'b1)
343         cnt_1us <= cnt_1us + 1'b1;
344     else
345         cnt_1us <= cnt_1us;    
346 
347 generate
348   if (WR_CH_EN[0]==1) begin: WR_EN
349     fifo_wr_64_64    u1_fifo_wr_64_64
350     (
351         .rst                 (ext_pre_pose                ),
352         .wr_clk                (pre_clk                    ),            
353         .rd_clk                (M_AXI_ACLK                    ),           
354         .din                (o_data                        ),               
355         .wr_en                (o_data_de                    ),           
356         .rd_en                (axi_wdata_de                ),            
357         .dout                (axi_wdata                    ),              
358         .full                (wr_full                    ),                   
359         .empty                (wr_empty                    ),                 
360         .rd_data_count        (wr_rd_data_count            ), 
361         .wr_data_count        (wr_wr_data_count            )
362     );
363   end
364 endgenerate
365 
366 //AXI_RD
367 reg     [7:0]                        rd_index            ;
368 reg        [7:0]                        rd_index_r            ;
369 reg     [AXI_ADDR_WIDTH-1 : 0]          rd_base_addr        ;
370 
371 reg                                    rd_flag        ;
372 reg                                    rd_cmd_flag            ;
373 reg                                    rd_data_flag        ;
374 
375 reg                                  axi_arvalid            ;
376 reg     [AXI_ADDR_WIDTH-1:0]         axi_araddr            ;
377 reg                                  axi_rready            ;
378 
379 reg      [15:0]                        rd_hcnt                ;        
380 reg      [15:0]                        rd_vcnt                ;
381 
382 wire                                axi_rdata_de        ;    
383 wire    [RD_DATA_WIDTH-1:0]            axi_rdata            ;
384 
385 wire                                rd_full                ;
386 wire                                rd_empty            ;
387 wire    [13:0]                        rd_rd_data_count    ;
388 wire    [10:0]                       rd_wr_data_count    ;
389 
390 
391 always@(posedge M_AXI_ACLK)
392     if(!M_AXI_ARESETN)
393         rd_index <= AXI_BUF_SIZE[7:0];
394     else
395         case(WR_CH_EN[0])
396             1'b0: 
397                 if(i_wr_index>1'b1)
398                     rd_index <= i_wr_index-1'b1;
399                 else
400                     rd_index <= AXI_BUF_SIZE[7:0];    
401             1'b1: 
402                 if(wr_index>1'b1)
403                     rd_index <= wr_index-1'b1;
404                 else
405                     rd_index <= AXI_BUF_SIZE[7:0];
406                     
407             default:rd_index <= rd_index;
408         endcase            
409 
410 always@(posedge M_AXI_ACLK)
411     if(!M_AXI_ARESETN)
412         rd_index_r <= 'd0;
413     else
414         rd_index_r <= rd_index-1'b1;
415         
416 always@(posedge M_AXI_ACLK)
417     if(!M_AXI_ARESETN)
418         rd_base_addr <= 'd0;
419     else
420         rd_base_addr <= rd_index_r*addr_offset;
421 //读标志一直拉高
422 always@(posedge M_AXI_ACLK)
423     if(!M_AXI_ARESETN)
424         rd_flag <= 1'b0;
425     else if(RD_CH_EN[0]==1'b1&&axi_rd_start==1'b1)
426         rd_flag <= 1'b1;
427     else
428         rd_flag <= rd_flag;
429 //读命令标志,此时没有传输数据,表示可以传输读地址
430 always@(posedge M_AXI_ACLK)
431     if(!M_AXI_ARESETN)
432         rd_cmd_flag <= 1'b0;
433     else if(axi_arvalid==1'b1&&M_AXI_ARREADY==1'b1)
434         rd_cmd_flag <= 1'b0;
435     else if(rd_flag==1'b1&&rd_data_flag==1'b0)
436         rd_cmd_flag <= 1'b1;
437     else
438         rd_cmd_flag <= rd_cmd_flag;
439 //读数据标志,表示正在进行读数据操作
440 always@(posedge M_AXI_ACLK)
441     if(!M_AXI_ARESETN)
442         rd_data_flag <= 1'b0; 
443     else if(axi_rready==1'b1&&M_AXI_RVALID==1'b1&&M_AXI_RLAST==1'b1)
444         rd_data_flag <= 1'b0;
445     else if(axi_arvalid==1'b1&&M_AXI_ARREADY==1'b1)
446         rd_data_flag <= 1'b1;
447     else
448         rd_data_flag <= rd_data_flag;
449 //此时可以写入命令,并且写数据计数不够时拉高读地址有效信号
450 always@(posedge M_AXI_ACLK)
451     if(!M_AXI_ARESETN)
452         axi_arvalid <= 1'b0;
453     else if(axi_arvalid==1'b1&&M_AXI_ARREADY==1'b1)
454         axi_arvalid <= 1'b0;
455     else if(rd_cmd_flag==1'b1&&rd_wr_data_count<RD_BURST_LEN*4)     //小于四次突发的数据
456         axi_arvalid <= 1'b1;
457     else
458         axi_arvalid <= axi_arvalid;
459 //读地址更新
460 always@(posedge M_AXI_ACLK)
461     if(!M_AXI_ARESETN)
462         axi_araddr <= 'd0;
463     else if(M_AXI_RVALID==1'b1&&axi_rready==1'b1&&rd_hcnt==(RD_BURST_LEN-1'b1)&&rd_vcnt==rd_burst_times-1'b1)
464         axi_araddr <= rd_base_addr;
465     else if(axi_arvalid==1'b1&&M_AXI_ARREADY==1'b1)
466         axi_araddr <= axi_araddr + rd_burst_bytes;
467     else
468         axi_araddr <= axi_araddr;        
469 //读数据信号拉高时,准备接收数据
470 always@(posedge M_AXI_ACLK)
471     if(!M_AXI_ARESETN)
472         axi_rready <= 1'b0;
473     else if(rd_data_flag==1'b0)
474         axi_rready <= 1'b0;
475     else if(rd_data_flag==1'b1)
476         axi_rready <= 1'b1;
477     else
478         axi_rready <= axi_rready;
479                         
480 always@(posedge M_AXI_ACLK)
481     if(!M_AXI_ARESETN)
482         rd_hcnt <= 'd0;
483     else if(M_AXI_RVALID==1'b1&&axi_rready==1'b1&&rd_hcnt==RD_BURST_LEN-1'b1)
484         rd_hcnt <= 'd0;
485     else if(M_AXI_RVALID==1'b1&&axi_rready==1'b1)
486         rd_hcnt <= rd_hcnt + 1'b1;    
487     else
488         rd_hcnt <= rd_hcnt;
489 
490 always@(posedge M_AXI_ACLK)
491     if(!M_AXI_ARESETN)
492         rd_vcnt <= 'd0;
493     else if(M_AXI_RVALID==1'b1&&axi_rready==1'b1&&rd_hcnt==(RD_BURST_LEN-1'b1)&&rd_vcnt==rd_burst_times-1'b1)
494         rd_vcnt <= 'd0;
495     else if(M_AXI_RVALID==1'b1&&axi_rready==1'b1&&rd_hcnt==RD_BURST_LEN-1'b1)
496         rd_vcnt <= rd_vcnt + 1'b1;    
497     else
498         rd_vcnt <= rd_vcnt;
499 
500 assign axi_rdata_de = M_AXI_RVALID&&axi_rready;
501 assign axi_rdata = M_AXI_RDATA;
502 
503 generate
504   if (RD_CH_EN[0]==1) begin: RD_EN
505     fifo_rd_64_8    u1_fifo_rd_64_16
506     (
507         .wr_clk                (M_AXI_ACLK                    ),            
508         .rd_clk                (post_clk                    ),           
509         .din                (axi_rdata                    ),               
510         .wr_en                (axi_rdata_de                ),           
511         .rd_en                (post_de                    ),            
512         .dout                (post_data                    ),              
513         .full                (rd_full                    ),                   
514         .empty                (rd_empty                    ),                 
515         .rd_data_count        (rd_rd_data_count            ), 
516         .wr_data_count        (rd_wr_data_count            )
517     );
518   end
519 endgenerate
520 
521 
522 function integer clogb2 (input integer bit_depth);              
523     begin                                                           
524         for(clogb2=0; bit_depth>0; clogb2=clogb2+1)                   
525             bit_depth = bit_depth >> 1;                                 
526     end                                                           
527 endfunction  
528 
529 
530 assign     M_AXI_AWID            = 1'b0                            ;
531 assign     M_AXI_AWVALID        = axi_awvalid                    ;
532 assign     M_AXI_AWADDR        = AXI_ADDR_BASE + axi_awaddr    ;
533 assign     M_AXI_AWLEN            = WR_BURST_LEN - 1'b1            ;
534 assign     M_AXI_AWSIZE        = clogb2((WR_DATA_WIDTH/8)-1)    ;
535 assign     M_AXI_AWBURST        = 2'b01                            ;
536 assign     M_AXI_AWLOCK        = 1'b0                            ;
537 assign     M_AXI_AWCACHE        = 4'b0010                        ;
538 assign     M_AXI_AWPROT        = 3'b000                        ;
539 assign     M_AXI_AWQOS            = 4'b0000                        ;
540 assign     M_AXI_WVALID        = axi_wvalid                    ;
541 assign     M_AXI_WDATA            = axi_wdata                        ;
542 assign     M_AXI_WSTRB            = {(WR_DATA_WIDTH/8){1'b1}}        ;
543 assign     M_AXI_WLAST            = axi_wlast                        ;
544 assign     M_AXI_BREADY        = axi_bready                    ;
545 
546 assign     M_AXI_ARID            = 1'b0                            ;
547 assign     M_AXI_ARVALID        = axi_arvalid                    ;
548 assign     M_AXI_ARADDR        = AXI_ADDR_BASE + axi_araddr    ;
549 assign     M_AXI_ARLEN            = RD_BURST_LEN-1'b1                ;
550 assign     M_AXI_ARSIZE        = clogb2((RD_DATA_WIDTH/8)-1)    ;
551 assign     M_AXI_ARBURST        = 2'b01                            ;
552 assign     M_AXI_ARLOCK        = 1'b0                            ;
553 assign     M_AXI_ARCACHE        = 4'b0010                        ;
554 assign     M_AXI_ARPROT        = 3'b000                        ;
555 assign     M_AXI_ARQOS            = 4'b0000                        ;
556 assign     M_AXI_RREADY        = axi_rready                    ;
557 
558 //post
559 reg [15:0]     post_hcnt    ;
560 reg [15:0]     post_vcnt    ;
561 //
562 always@(posedge post_clk)
563     if(!M_AXI_ARESETN)
564         post_start <= 1'b0;
565     else if(rd_rd_data_count>=RD_BURST_LEN*4*RD_DATA_WIDTH/I_DW)
566         post_start <= 1'b1;
567     else 
568         post_start <= post_start;
569 
570 always@(posedge post_clk)
571     if(!M_AXI_ARESETN)
572         post_hcnt <= 'd0;
573     else if(post_hcnt==RD_IW-1&&post_de==1'b1)
574         post_hcnt <= 'd0;
575     else if(post_de==1'b1)
576         post_hcnt <= post_hcnt + 1'b1;
577     else
578         post_hcnt <= post_hcnt;        
579 
580 always@(posedge post_clk)
581     if(!M_AXI_ARESETN)
582         post_vcnt <= 'd0;
583     else if(post_hcnt==RD_IW-1'b1&&post_vcnt==RD_IH-1&&post_de==1'b1)
584         post_vcnt <= 'd0;
585     else if(post_hcnt==RD_IW-1'b1&&post_de==1'b1)
586         post_vcnt <= post_vcnt + 1'b1;
587     else
588         post_vcnt <= post_vcnt;
589                                                             
590 endmodule
 1 `timescale 1ns / 1ps
 2 //////////////////////////////////////////////////////////////////////////////////
 3 // Company: 
 4 // Engineer: 
 5 // 
 6 // Create Date: 2019/05/27 22:56:38
 7 // Design Name: 
 8 // Module Name: data_joint
 9 // Project Name: 
10 // Target Devices: 
11 // Tool Versions: 
12 // Description: 
13 // 
14 // Dependencies: 
15 // 
16 // Revision:
17 // Revision 0.01 - File Created
18 // Additional Comments:
19 // 
20 //////////////////////////////////////////////////////////////////////////////////
21 
22 
23 module data_joint #(
24     parameter IW_WIDTH=16,
25     parameter OW_WIDTH=64
26 )
27 (    
28     input                         clk            ,
29     input                       rst_n        ,
30     input                       i_data_de   ,
31     input          [IW_WIDTH-1:0]    i_data        ,
32     output  reg                 o_data_de   ,            
33     output  reg  [OW_WIDTH-1:0] o_data        
34 );
35 
36 reg  [7:0] cnt;
37 
38 
39 localparam integer  num = OW_WIDTH/IW_WIDTH;
40 
41 always@(posedge clk)
42     if(!rst_n)
43         cnt <= 8'd0;
44     else if(cnt==num-1&&i_data_de)
45         cnt <= 8'd0;
46     else if(i_data_de==1'b1&&num>1)
47         cnt <= cnt + 1'b1;
48     else
49         cnt <= cnt;
50 
51 always@(posedge clk)
52     if(!rst_n)
53         o_data <= {OW_WIDTH{1'b0}};
54     else if(i_data_de==1'b1&&num>1)
55         o_data <= {o_data[OW_WIDTH-IW_WIDTH-1:0],i_data};
56     else if(num==1)
57         o_data <= i_data;
58     else
59         o_data <= o_data;
60         
61 always@(posedge clk)
62     if(!rst_n)
63         o_data_de <= 1'b0;
64     else if(cnt==num-1&&i_data_de&&num>1)
65         o_data_de <= 1'b1;
66     else if(num==1)
67         o_data_de <= i_data_de;        
68     else
69         o_data_de <= 1'b0;    
70 
71 
72 endmodule 

脉冲延迟模块

 1 `timescale 1ns / 1ps
 2 //////////////////////////////////////////////////////////////////////////////////
 3 // Company: 
 4 // Engineer: 
 5 // 
 6 // Create Date: 2022/01/09 16:47:38
 7 // Design Name: 
 8 // Module Name: data_sync_ext
 9 // Project Name: 
10 // Target Devices: 
11 // Tool Versions: 
12 // Description: 
13 // 
14 // Dependencies: 
15 // 
16 // Revision:
17 // Revision 0.01 - File Created
18 // Additional Comments:
19 // 
20 //////////////////////////////////////////////////////////////////////////////////
21 module data_sync_ext(
22     input         clka        ,
23     input         rst_n        ,    
24     input         pulse_a        ,
25     output     reg    ext_pulse_a    
26 );
27 
28 reg    [7:0]    pulse_a_r        ;
29 
30 always@(posedge clka)
31     if(!rst_n)
32         pulse_a_r <= 8'd0;
33     else
34         pulse_a_r <= {pulse_a_r[6:0],pulse_a};
35     
36 always@(posedge clka)
37     if(!rst_n)    
38         ext_pulse_a <= 1'b0;
39     else
40         ext_pulse_a <= |pulse_a_r; 
41 
42  
43 endmodule

数据拼接模块,另一个方法是使用读写位宽不同的FIFO进行缓存,但是要考虑数据的排列顺序,先进入的数据会放到高位,最后读取时,也是高位先出

(1条消息) 读写位宽不同的FIFO,数据输入输出顺序是怎么样的?BRAM又如何呢?_视觉患者leon的博客-CSDN博客

 1 `timescale 1ns / 1ps
 2 //////////////////////////////////////////////////////////////////////////////////
 3 // Company: 
 4 // Engineer: 
 5 // 
 6 // Create Date: 2019/05/27 22:56:38
 7 // Design Name: 
 8 // Module Name: data_joint
 9 // Project Name: 
10 // Target Devices: 
11 // Tool Versions: 
12 // Description: 
13 // 
14 // Dependencies: 
15 // 
16 // Revision:
17 // Revision 0.01 - File Created
18 // Additional Comments:
19 // 
20 //////////////////////////////////////////////////////////////////////////////////
21 
22 
23 module data_joint #(
24     parameter IW_WIDTH=16,
25     parameter OW_WIDTH=64
26 )
27 (    
28     input                         clk            ,
29     input                       rst_n        ,
30     input                       i_data_de   ,
31     input          [IW_WIDTH-1:0]    i_data        ,
32     output  reg                 o_data_de   ,            
33     output  reg  [OW_WIDTH-1:0] o_data        
34 );
35 
36 reg  [7:0] cnt;
37 
38 
39 localparam integer  num = OW_WIDTH/IW_WIDTH;
40 
41 always@(posedge clk)
42     if(!rst_n)
43         cnt <= 8'd0;
44     else if(cnt==num-1&&i_data_de)
45         cnt <= 8'd0;
46     else if(i_data_de==1'b1&&num>1)
47         cnt <= cnt + 1'b1;
48     else
49         cnt <= cnt;
50 
51 always@(posedge clk)
52     if(!rst_n)
53         o_data <= {OW_WIDTH{1'b0}};
54     else if(i_data_de==1'b1&&num>1)
55         o_data <= {o_data[OW_WIDTH-IW_WIDTH-1:0],i_data};
56     else if(num==1)
57         o_data <= i_data;
58     else
59         o_data <= o_data;
60         
61 always@(posedge clk)
62     if(!rst_n)
63         o_data_de <= 1'b0;
64     else if(cnt==num-1&&i_data_de&&num>1)
65         o_data_de <= 1'b1;
66     else if(num==1)
67         o_data_de <= i_data_de;        
68     else
69         o_data_de <= 1'b0;    
70 
71 
72 endmodule

 

 注意!!! 每帧的VS上升沿需要对写FIFO复位,且复位周期大概在240ns,此时数据不能写进去,所以如果图像vs 和 de 信号间隔很近,需要对de信号进行适当的延时