非同步fifo with 讀控制

来源:https://www.cnblogs.com/LJH-NIUBI/archive/2018/05/12/9029564.html
-Advertisement-
Play Games

之前做LDPC編碼器時,學習了一下非同步FIFO的相關知識,主要參考了http://www.cnblogs.com/aslmer/p/6114216.html,併在此基礎上根據項目需求,添加了一個讀控制模塊。因為後面編碼模塊的需要,因此fifo_in模塊要求滿足下麵功能: a、存儲輸入數據 b、當fi ...


之前做LDPC編碼器時,學習了一下非同步FIFO的相關知識,主要參考了http://www.cnblogs.com/aslmer/p/6114216.html,併在此基礎上根據項目需求,添加了一個讀控制模塊。因為後面編碼模塊的需要,因此fifo_in模塊要求滿足下麵功能:

a、存儲輸入數據

b、當fifo中存儲數據的個數達到x時,產生激勵信號,並連續輸出這x個數據

c、當後面編碼模塊處於編碼過程中時,禁止數據輸出

d、x是根據不同編碼碼率而確定的,因此要時常變化(這個功能時聯合其他模塊共同實現的)

 

 

1、fifo_in.v  是頂層模塊,作用是將各個小模塊例化聯繫起來。

輸入信號encoding是由後面編碼模塊產生,表示是否在編碼過程中。輸入信號in_length輸入的數就是個數要求x,由碼率選擇模塊產生。

輸出信號start_code是給編碼模塊的激勵信號。輸出信號rd_over表示當前一串數據已經輸出完畢,主要用於給碼率選擇模塊改變x的值時用。

 1 module fifo_in
 2 (
 3     //input
 4     input        wr_clk,
 5     input        encoding,
 6     input     wr_rst_n,
 7     input     wr_ask,
 8     input     [2:0] wr_data,
 9     input     rd_clk,
10     input     rd_rst_n,
11     input        [9:0] in_length,
12     //output
13     output     wr_full,//寫滿
14     output     rd_empty,//讀空
15     output     [2:0] rd_data,
16     output    rd_en,
17     output    start_code,
18     output    rd_over
19 );
20  wire wr_en;
21  wire    [9:0] wr_addr;
22  wire [9:0] rd_addr;
23  wire    rd_ask;
24  
25  assign wr_en =(wr_ask) && (!wr_full);
26 fifo_in_control fifo_in_control
27 (
28     //input
29     .wr_clk(wr_clk),
30     .wr_rst_n(wr_rst_n),
31     .wr_ask(wr_ask),
32     //.wr_data(wr_data),
33     .rd_clk(rd_clk),
34     .rd_rst_n(rd_rst_n),
35     .rd_ask(rd_ask),
36     //output
37     .wr_full(wr_full),//寫滿
38     .rd_empty(rd_empty),//讀空
39     .wr_addr(wr_addr),
40     .rd_addr(rd_addr)
41     //output     [2:0] rd_data
42 );
43 fifo_in_rd_control fifo_in_rd_control
44 (
45     //input
46     .rd_clk(rd_clk),
47     .rd_rst_n(rd_rst_n),
48     .rd_addr(rd_addr),
49     .wr_addr(wr_addr),
50     .in_length(in_length),
51     .encoding(encoding),
52     //output
53     .rd_ask(rd_ask),
54     .start_code_1(start_code),
55     .rd_en_1(rd_en),
56     .rd_over(rd_over)
57     
58 );
59 fifo_in_mem fifo_in_mem (
60     .data(wr_data),
61     .rdaddress(rd_addr),
62     .rdclock(rd_clk),
63     .wraddress(wr_addr),
64     .wrclock(wr_clk),
65     .wren(wr_en),
66     .q(rd_data)
67 );
68 endmodule
View Code

 

2、fifo_in_control.v 是非同步fifo的主要程式,我從上面那個網址抄來的,網址內的講解也非常清楚,使用格雷碼來避免讀寫地址的混亂。

  1 module fifo_in_control
  2 (
  3     //input
  4     input        wr_clk,
  5     input     wr_rst_n,
  6     input     wr_ask,
  7     //input     [2:0] wr_data,
  8     input     rd_clk,
  9     input     rd_rst_n,
 10     input     rd_ask,
 11     //output
 12     output     reg    wr_full,//寫滿
 13     output     reg    rd_empty,//讀空
 14     output    [9:0] wr_addr,
 15     output    [9:0] rd_addr
 16     //output     [2:0] rd_data
 17 );
 18  
 19  reg    [10:0] rd_proint_gray;//格雷碼形式的寫指針
 20  reg    [10:0] rd_proint_gray_1;//格雷碼形式的寫指針_延時一個寫時鐘
 21  reg    [10:0] rd_proint_gray_2;//格雷碼形式的寫指針_延時兩個寫時鐘(同步到寫時鐘的讀指針)
 22 
 23  reg     [10:0] wr_proint_gray;//格雷碼形式的讀指針
 24  reg     [10:0] wr_proint_gray_1;//格雷碼形式的讀指針_延時一個讀時鐘
 25  reg     [10:0] wr_proint_gray_2;//格雷碼形式的讀指針_延時兩個讀時鐘(同步到讀時鐘的寫指針)
 26  
 27  reg    [10:0] wr_proint_bin;//二進位形式的寫指針
 28  wire    [10:0] wr_proint_bin_next;
 29  wire    [10:0] wr_proint_gray_next;
 30  wire    wr_full_val;
 31  
 32  reg    [10:0] rd_proint_bin;//二進位形式的讀指針
 33  wire    [10:0] rd_proint_bin_next;
 34  wire    [10:0] rd_proint_gray_next;
 35  wire    rd_empty_val;
 36 //---------------------------------------------------------------------------------
 37  always @(posedge wr_clk or negedge wr_rst_n)//讀指針同步到寫時鐘
 38     begin
 39         if (!wr_rst_n)
 40             begin
 41                 rd_proint_gray_1 <= 0;          
 42                 rd_proint_gray_2 <= 0;
 43             end           
 44         else
 45             begin        
 46                 rd_proint_gray_1 <= rd_proint_gray;
 47                 rd_proint_gray_2 <= rd_proint_gray_1;
 48             end
 49     end
 50 //--------------------------------------------------------------------------------
 51  always @(posedge rd_clk or negedge rd_rst_n)//寫指針同步到讀時鐘
 52     begin
 53         if (!rd_rst_n)
 54             begin
 55                 wr_proint_gray_1 <= 0;
 56                 wr_proint_gray_2 <= 0;
 57             end 
 58         else 
 59             begin
 60                 wr_proint_gray_1 <= wr_proint_gray;
 61                 wr_proint_gray_2 <= wr_proint_gray_1;
 62             end
 63     end
 64 //---------------------------------------------------------------------------------
 65 //寫滿判決
 66  always @(posedge wr_clk or negedge wr_rst_n)
 67     begin
 68         if (!wr_rst_n)
 69           {wr_proint_bin, wr_proint_gray} <= 0;   
 70       else         
 71           {wr_proint_bin, wr_proint_gray} <= {wr_proint_bin_next, wr_proint_gray_next};
 72     end
 73  
 74 // Memory write-address pointer (okay to use binary to address memory) 
 75  assign wr_addr = wr_proint_bin[9:0];
 76  assign wr_proint_bin_next  = wr_proint_bin + (wr_ask & ~wr_full);
 77  assign wr_proint_gray_next = (wr_proint_bin_next>>1) ^ wr_proint_bin_next; //二進位轉為格雷碼
 78  assign wr_full_val = (wr_proint_gray_next=={~rd_proint_gray_2[10:9],rd_proint_gray_2[8:0]}); //當最高位和次高位不同其餘位相同時則寫指針超前於讀指針一圈,即寫滿
 79  
 80  always @(posedge wr_clk or negedge wr_rst_n)
 81         begin
 82             if (!wr_rst_n)
 83                 wr_full <= 1'b0;   
 84             else     
 85                 wr_full <= wr_full_val;
 86         end
 87 //----------------------------------------------------------------------------------
 88 //讀空判決
 89  always @(posedge rd_clk or negedge rd_rst_n)
 90     begin
 91         if (!rd_rst_n)
 92             begin
 93                 rd_proint_bin <= 0;
 94                 rd_proint_gray <= 0;
 95             end
 96         else
 97             begin        
 98                 rd_proint_bin <= rd_proint_bin_next; //直接作為存儲實體的地址
 99                 rd_proint_gray <= rd_proint_gray_next;
100             end
101     end
102 // Memory read-address pointer (okay to use binary to address memory)
103  assign rd_addr = rd_proint_bin[9:0]; //直接作為存儲實體的地址
104  assign rd_proint_bin_next = rd_proint_bin + (rd_ask & ~rd_empty);//不空且有讀請求的時候讀指針加1
105  assign rd_proint_gray_next = (rd_proint_bin_next>>1) ^ rd_proint_bin_next;//將二進位的讀指針轉為格雷碼
106 // FIFO empty when the next rptr == synchronized wptr or on reset 
107  assign rd_empty_val = (rd_proint_gray_next == wr_proint_gray_2); //當讀指針等於同步後的寫指針,則為空。
108   
109  always @(posedge rd_clk or negedge rd_rst_n)
110     begin
111         if (!rd_rst_n)
112             rd_empty <= 1'b1;
113         else
114             rd_empty <= rd_empty_val;
115     end
116 
117 endmodule
View Code

 

3、fifo_in_rd_control.v 是fifo_in的讀控制模塊,狀態機分為五個狀態。數據length記錄當前fifo中存儲數據的個數,當其大於x(in_length)時,可以進行輸出。當fifo中存儲數據的個數一直大於x時,兩串輸出數據的間隔只有幾個時鐘周期,有時會造成encoding信號還沒有生效,新的一串數據已經開始輸出,因此設置delay狀態,稍等幾個周期,確定編碼模塊是否在工作。

  1 module fifo_in_rd_control
  2 (
  3     //input
  4     input        rd_clk,
  5     input        rd_rst_n,
  6     input        [9:0] rd_addr,
  7     input        [9:0] wr_addr,
  8     input        [9:0] in_length,
  9     input        encoding,
 10     //output
 11     output    reg     rd_ask,
 12     output    reg     start_code_1,
 13     output    reg     rd_en_1,
 14     output     reg    rd_over
 15 );
 16  reg    [9:0] length;//當前fifo中存儲數據的個數
 17  reg    [4:0] state;
 18  reg     [9:0] count;//計輸出數據的個數
 19 // reg     [9:0] in_length_next;
 20  //reg    rd_over;
 21  reg     start_code;
 22  reg    rd_en;
 23  reg     [1:0]i;//延時幾個時鐘
 24  
 25  parameter    hold     = 5'b00001;
 26  parameter     delay    = 5'b00010;
 27  parameter    start = 5'b00100;
 28  parameter    read     = 5'b01000;
 29  parameter    over     = 5'b10000;
 30  
 31  
 32  always @(posedge rd_clk or negedge rd_rst_n)
 33     begin
 34         start_code_1 <= start_code;
 35         rd_en_1 <= rd_en;
 36     end
 37  always @(posedge rd_clk or negedge rd_rst_n)
 38     begin
 39         if(!rd_rst_n)
 40             begin
 41                 state <= hold;
 42                 rd_ask <= 0;
 43                 start_code <= 0;
 44                 rd_en <= 0;
 45                 rd_over <= 0;
 46             end
 47         else if(encoding)
 48             begin
 49                 state <= hold;
 50                 rd_ask <= 0;
 51                 start_code <= 0;
 52                 rd_en <= 0;
 53                 rd_over <= 0;
 54             end
 55         else
 56             case(state)
 57                 hold:
 58                     if(in_length <= length)
 59                         begin
 60                             state <= delay;
 61                             rd_over <= 0;
 62                             i <= 2'b00;
 63                         end
 64                     else
 65                         begin
 66                             state <= hold;
 67                             rd_over <= 0;
 68                         end
 69                 delay:
 70                     if(i >= 2)
 71                         state <= start;
 72                     else
 73                         i <= i + 1;
 74                 start:
 75                     begin
 76                         state <= read;
 77                         start_code <= 1;
 78                     end
 79                 read:
 80                     if(count == in_length-1)
 81                         begin
 82                             state <= over;
 83                             rd_en <= 0;
 84                             rd_ask <= 0;
 85                         end
 86                     else
 87                         begin
 88                             state <= read;
 89                             rd_en <= 1;
 90                             rd_ask <= 1;
 91                             start_code <= 0;
 92                         end
 93                 over:
 94                     begin
 95                         state <= hold;
 96                         rd_over <= 1;
 97                     end
 98                 default:state <= hold;
 99             endcase
100     end        
101  
102  always @(posedge rd_clk or negedge rd_rst_n)
103     begin
104         if(!rd_rst_n)
105             length <= 0;
106         else if(wr_addr < rd_addr)
107             length <= (10'd1023 ^ rd_addr) + wr_addr + 10'd1;
108         else
109             length <= wr_addr - rd_addr;
110     end
111 
112  always @(posedge rd_clk or negedge rd_rst_n)
113     begin
114         if(!rd_rst_n)
115             count <= 10'd0;
116         else if(rd_en)
117             count <= count + 10'd1;
118         else if(start_code)
119             count <= 10'd0;
120         else
121             count <= count;
122     end
123     
124 // always @(posedge rd_clk or negedge rd_rst_n)
125 //    begin
126 //        if(!rd_rst_n)
127 //            in_length_next <= in_length;
128 //        else if(rd_over)
129 //            in_length_next <= in_length;
130 //        else
131 //            in_length_next <= in_length_next;
132 //    end
133     
134 endmodule
View Code

 

4、fifo_in_mem.v 生成存儲實體,FIFO 的本質是RAM,因此在設計存儲實體的時候有兩種方法:用數組存儲數據或者調用RAM的IP核。我是採用IP核的方法。

  1 // megafunction wizard: %RAM: 2-PORT%
  2 // GENERATION: STANDARD
  3 // VERSION: WM1.0
  4 // MODULE: altsyncram 
  5 
  6 // ============================================================
  7 // File Name: fifo_in_mem.v
  8 // Megafunction Name(s):
  9 //             altsyncram
 10 //
 11 // Simulation Library Files(s):
 12 //             altera_mf
 13 // ============================================================
 14 // ************************************************************
 15 // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
 16 //
 17 // 17.1.0 Build 590 10/25/2017 SJ Standard Edition
 18 // ************************************************************
 19 
 20 
 21 //Copyright (C) 2017  Intel Corporation. All rights reserved.
 22 //Your use of Intel Corporation's design tools, logic functions 
 23 //and other software and tools, and its AMPP partner logic 
 24 //functions, and any output files from any of the foregoing 
 25 //(including device programming or simulation files), and any 
 26 //associated documentation or information are expressly subject 
 27 //to the terms and conditions of the Intel Program License 
 28 //Subscription Agreement, the Intel Quartus Prime License Agreement,
 29 //the Intel FPGA IP License Agreement, or other applicable license
 30 //agreement, including, without limitation, that your use is for
 31 //the sole purpose of programming logic devices manufactured by
 32 //Intel and sold by Intel or its authorized distributors.  Please
 33 //refer to the applicable agreement for further details.
 34 
 35 
 36 // synopsys translate_off
 37 `timescale 1 ps / 1 ps
 38 // synopsys translate_on
 39 module fifo_in_mem (
 40     data,
 41     rdaddress,
 42     rdclock,
 43     wraddress,
 44     wrclock,
 45     wren,
 46     q);
 47 
 48     input    [2:0]  data;
 49     input    [9:0]  rdaddress;
 50     input      rdclock;
 51     input    [9:0]  wraddress;
 52     input      wrclock;
 53     input      wren;
 54     output    [2:0]  q;
 55 `ifndef ALTERA_RESERVED_QIS
 56 // synopsys translate_off
 57 `endif
 58     tri1      wrclock;
 59     tri0      wren;
 60 `ifndef ALTERA_RESERVED_QIS
 61 // synopsys translate_on
 62 `endif
 63 
 64     wire [2:0] sub_wire0;
 65     wire [2:0] q = sub_wire0[2:0];
 66 
 67     altsyncram    altsyncram_component (
 68                 .address_a (wraddress),
 69                 .address_b (rdaddress),
 70                 .clock0 (wrclock),
 71                 .clock1 (rdclock),
 72                 .data_a (data),
 73                 .wren_a (wren),
 74                 .q_b (sub_wire0),
 75                 .aclr0 (1'b0),
 76                 .aclr1 (1'b0),
 77                 .addressstall_a (1'b0),
 78                 .addressstall_b (1'b0),
 79                 .byteena_a (1'b1),
 80                 .byteena_b (1'b1),
 81                 .clocken0 (1'b1),
 82                 .clocken1 (1'b1),
 83                 .clocken2 (1'b1),
 84                 .clocken3 (1'b1),
 85                 .data_b ({3{1'b1}}),
 86                 .eccstatus (),
 87                 .q_a (),
 88                 .rden_a (1'b1),
 89                 .rden_b (1'b1),
 90                 .wren_b (1'b0));
 91     defparam
 92         altsyncram_component.address_aclr_b = "NONE",
 93         altsyncram_component.address_reg_b = "CLOCK1",
 94         altsyncram_component.clock_enable_input_a = "BYPASS",
 95         altsyncram_component.clock_enable_input_b = "BYPASS",
 96         altsyncram_component.clock_enable_output_b = "BYPASS",
 97         altsyncram_component.intended_device_family = "Cyclone V",
 98         altsyncram_component.lpm_type = "altsyncram",
 99         altsyncram_component.numwords_a = 1024,
100         altsyncram_component.numwords_b = 1024,
101         altsyncram_component.operation_mode = "DUAL_PORT",
102         altsyncram_component.outdata_aclr_b = "NONE",
103         altsyncram_component.outdata_reg_b = "CLOCK1",
104         altsyncram_component.power_up_uninitialized = "FALSE",
105         altsyncram_component.widthad_a = 10,
106         altsyncram_component.widthad_b = 10,
107         altsyncram_component.width_a = 3,
108         altsyncram_component.width_b = 3,
109         altsyncram_component.width_byteena_a = 1;
110 
111<

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 視頻 dubbo視頻 spring視頻 springcloud視頻 ...
  • 裝飾器的語法為 @dec_name ,置於函數定義之前。如: import atexit @atexit.register def goodbye(): print('Goodbye!') print('Script end here') atexit.register 是一個裝飾器,它的作用是將被 ...
  • 1. 網路:把雙方或者多方的設備(電腦,智能手機,ipad等)連接起來的一個工具 1.1 學習網路的目的: 通過網路把數據從一方傳遞到另外一方,完成數據的共用 2. ip地址 2.1: ip地址:標識網路中唯一的一臺設備 2.2. ip地址的作用:通過ip地址找到唯一的一臺設備,然後給設備發送數據 ...
  • 摘要 :電腦技術的發展,推動了編程領域的發展,C++ 編程作為編程中應用最廣泛、最便捷、最簡明的一種編程語言, 通過它的應用能夠不斷提升編程質量。鑒於此,本文對變數命名、動態記憶體、概念混淆這三種 C++ 編程中常見問題與解決途徑進行集中的解決與分析。旨在為了不斷提升現今 C++ 編程程式的質量獻力 ...
  • # coding:utf-8 import turtle as tt.pensize(4)t.hideturtle()t.colormode(255)t.color((255,155,192),"pink")t.setup(840,500)t.speed(10)#鼻子t.pu()t.goto(-10 ...
  • 恢復內容開始 只有MD5的超鏈接可以點,點進去看看, 我寫這個的爬蟲的目的是下載樣本,只關心樣本的下載地址,並不關心其他的信息。 現在我們可以理清下思路: 提取規則 先從第一頁開始爬起 scrapy支持xss選擇器和css選擇器,一般是用哪個比較方便就用哪個。 對應鏈接的xpath選擇器為 //td ...
  • SpringBoot自定義攔截器實現IP白名單功能 轉載請註明源地址:http://www.cnblogs.com/funnyzpc/p/8993331.html 首先,相關功能已經上線了,且先讓我先禱告一番: 阿門~ (-__-) 額,正文開始前我先說兩句吧,能完成這個功能十分感謝csdn網友的一 ...
  • 因為互聯網協議包含了上百種協議標準,但是最重要的兩個協議是TCP和IP協議,所以,大家把互聯網的協議簡稱TCP/IP協議。 通信的時候,雙方必須知道對方的標識,好比發郵件必須知道對方的郵件地址。互聯網上每個電腦的唯一標識就是IP地址,類似 123.123.123.123。如果一臺電腦同時接入到兩 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...