在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > FPGA:數(shù)字示波器 2 - 雙端口 RAM

            FPGA:數(shù)字示波器 2 - 雙端口 RAM

            作者: 時間:2024-01-12 來源:EEPW編譯 收藏

            FIFO使我們能夠非常快速地獲得工作設(shè)計。
            但對于我們簡單的示波器來說,這有點矯枉過正。

            我們需要一種機(jī)制來存儲來自一個時鐘域(100MHz)的數(shù)據(jù),并在另一個時鐘域(25MHz)中讀取數(shù)據(jù)。 一個簡單的雙端口RAM就可以做到這一點。 缺點是兩個時鐘域之間的所有同步(FIFO為我們所做的)現(xiàn)在必須“手動”完成。

            本文引用地址:http://www.biyoush.com/article/202401/454719.htm

            觸發(fā)

            “基于 FIFO”的示波器設(shè)計沒有明確的觸發(fā)機(jī)制。
            讓我們改變一下。 現(xiàn)在,每次從串行端口接收到字符時,示波器都會被觸發(fā)。 當(dāng)然,這仍然不是一個非常有用的設(shè)計,但我們稍后會對其進(jìn)行改進(jìn)。

            我們使用“async_receiver”從串行端口接收數(shù)據(jù):

            wire [7:0] RxD_data;
            async_receiver async_rxd(.clk(clk), .RxD(RxD), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data));


            每當(dāng)收到一個新角色時,“RxD_data_ready”就會升高一個時鐘。 我們用它來觸發(fā)示波器。

            同步

            我們需要將這種“RxD_data_ready變高”的信息從“clk”(25MHz)域傳輸?shù)健癱lk_flash”(100MHz)域。

            首先,當(dāng)接收到字符時,信號“startAcquisition”變?yōu)楦唠娖健?/span>

            reg startAcquisition;
            wire AcquisitionStarted;

            always @(posedge clk)
            if(~startAcquisition)
              startAcquisition <= RxD_data_ready;
            else
            if(AcquisitionStarted)
              startAcquisition <= 0;


            我們使用 2 個觸發(fā)器形式的同步器(將此“startAcquisition”傳輸?shù)搅硪粋€時鐘域)。

            reg startAcquisition1; always @(posedge clk_flash) startAcquisition1 <= startAcquisition;
            reg startAcquisition2; always @(posedge clk_flash) startAcquisition2 <= startAcquisition1;


            最后,一旦另一個時鐘域“看到”信號,它就會“回復(fù)”(使用另一個同步器“獲取”)。

            reg Acquiring;
            always @(posedge clk_flash)
            if(~Acquiring)
              Acquiring <= startAcquisition2;  // start acquiring?
            else
            if(&wraddress)  // done acquiring?
              Acquiring <= 0;

            reg Acquiring1; always @(posedge clk) Acquiring1 <= Acquiring;
            reg Acquiring2; always @(posedge clk) Acquiring2 <= Acquiring1;
            assign AcquisitionStarted = Acquiring2;


            回復(fù)將重置原始信號。

            雙端口RAM

            現(xiàn)在觸發(fā)器可用,我們需要一個雙端口RAM來存儲數(shù)據(jù)。
            請注意 RAM 的每一側(cè)如何使用不同的時鐘。

            ram512 ram_flash(
              .data(data_flash_reg), .wraddress(wraddress), .wren(Acquiring), .wrclock(clk_flash),
              .q(ram_output), .rdaddress(rdaddress), .rden(rden), .rdclock(clk)

            );


            使用二進(jìn)制計數(shù)器可以輕松創(chuàng)建 ram 地址總線。
            首先是寫地址:

            reg [8:0] wraddress;
            always @(posedge clk_flash) if(Acquiring) wraddress <= wraddress + 1;


            和讀取地址:

            reg [8:0] rdaddress;
            reg Sending;
            wire TxD_busy;

            always @(posedge clk)
            if(~Sending)
              Sending <= AcquisitionStarted;
            else
            if(~TxD_busy)
            begin
              rdaddress <= rdaddress + 1;
              if(&rdaddress) Sending <= 0;
            end


            請注意每個計數(shù)器如何使用不同的時鐘。

            最后,我們將數(shù)據(jù)發(fā)送到 PC:

            wire TxD_start = ~TxD_busy & Sending;
            wire rden = TxD_start;

            wire [7:0] ram_output;
            async_transmitter async_txd(.clk(clk), .TxD(TxD), .TxD_start(TxD_start), .TxD_busy(TxD_busy), .TxD_data(ram_output));

            完整的設(shè)計

            module oscillo(clk, RxD, TxD, clk_flash, data_flash);
            input clk;
            input RxD;
            output TxD;

            input clk_flash;
            input [7:0] data_flash;

            ///////////////////////////////////////////////////////////////////
            wire [7:0] RxD_data;
            async_receiver async_rxd(.clk(clk), .RxD(RxD), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data));

            reg startAcquisition;
            wire AcquisitionStarted;

            always @(posedge clk)
            if(~startAcquisition)
              startAcquisition <= RxD_data_ready;
            else
            if(AcquisitionStarted)
              startAcquisition <= 0;

            reg startAcquisition1; always @(posedge clk_flash) startAcquisition1 <= startAcquisition ;
            reg startAcquisition2; always @(posedge clk_flash) startAcquisition2 <= startAcquisition1;

            reg Acquiring;
            always @(posedge clk_flash)
            if(~Acquiring)
              Acquiring <= startAcquisition2;
            else
            if(&wraddress)
              Acquiring <= 0;

            reg [8:0] wraddress;
            always @(posedge clk_flash) if(Acquiring) wraddress <= wraddress + 1;

            reg Acquiring1; always @(posedge clk) Acquiring1 <= Acquiring;
            reg Acquiring2; always @(posedge clk) Acquiring2 <= Acquiring1;
            assign AcquisitionStarted = Acquiring2;

            reg [8:0] rdaddress;
            reg Sending;
            wire TxD_busy;

            always @(posedge clk)
            if(~Sending)
              Sending <= AcquisitionStarted;
            else
            if(~TxD_busy)
            begin
              rdaddress <= rdaddress + 1;
              if(&rdaddress) Sending <= 0;
            end

            wire TxD_start = ~TxD_busy & Sending;
            wire rden = TxD_start;

            wire [7:0] ram_output;
            async_transmitter async_txd(.clk(clk), .TxD(TxD), .TxD_start(TxD_start), .TxD_busy(TxD_busy), .TxD_data(ram_output));

            ///////////////////////////////////////////////////////////////////
            reg [7:0] data_flash_reg; always @(posedge clk_flash) data_flash_reg <= data_flash;

            ram512 ram_flash(
              .data(data_flash_reg), .wraddress(wraddress), .wren(Acquiring), .wrclock(clk_flash),
              .q(ram_output), .rdaddress(rdaddress), .rden(rden), .rdclock(clk)
            );

            endmodule




            關(guān)鍵詞: FPGA 數(shù)字示波器

            評論


            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉