色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

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

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

          作者: 時(shí)間:2024-01-12 來(lái)源:EEPW編譯 收藏

          FIFO使我們能夠非常快速地獲得工作設(shè)計(jì)。
          但對(duì)于我們簡(jiǎn)單的示波器來(lái)說(shuō),這有點(diǎn)矯枉過(guò)正。

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

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

          觸發(fā)

          “基于 FIFO”的示波器設(shè)計(jì)沒(méi)有明確的觸發(fā)機(jī)制。
          讓我們改變一下。 現(xiàn)在,每次從串行端口接收到字符時(shí),示波器都會(huì)被觸發(fā)。 當(dāng)然,這仍然不是一個(gè)非常有用的設(shè)計(jì),但我們稍后會(huì)對(duì)其進(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)收到一個(gè)新角色時(shí),“RxD_data_ready”就會(huì)升高一個(gè)時(shí)鐘。 我們用它來(lái)觸發(fā)示波器。

          同步

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

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

          reg startAcquisition;
          wire AcquisitionStarted;

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


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

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


          最后,一旦另一個(gè)時(shí)鐘域“看到”信號(hào),它就會(huì)“回復(fù)”(使用另一個(gè)同步器“獲取”)。

          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ù)將重置原始信號(hào)。

          雙端口RAM

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

          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)制計(jì)數(shù)器可以輕松創(chuàng)建 ram 地址總線。
          首先是寫(xiě)地址:

          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


          請(qǐng)注意每個(gè)計(jì)數(shù)器如何使用不同的時(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è)計(jì)

          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ù)字示波器

          評(píng)論


          相關(guān)推薦

          技術(shù)專(zhuān)區(qū)

          關(guān)閉