強者蕭兄的問題如下:
(1)問題1
我想做出以下這個功能,內附verilog與vhdl模擬的結果timing圖
這是用Verilog的實現
當然我用VHDL可以寫一個很Verilog style的VHDL來實現這個功能沒問題
但我發現VHDL本身就提供rising_edge( )這個函數,
一般都是用來取代if clk'event and clk = '1'
我想利用rising_edge( )來實現我這個需求
以下是我寫的vhdl,但發現模擬結果不正確
若我想用rising_edge來寫,我該怎麼改?
//========== 以上蕭兄的問題1結束 ==========
看到這類問題
我的第一個直覺就是他code寫錯了
果不其然
他犯了全天下男人都會犯的錯(咦???)
我們先來看一下他的code吧
library ieee; use ieee.std_logic_1164.all; entity detect_rising_edge is port ( clk : in std_logic; rst_n : in std_logic; d : in std_logic; q : out std_logic ); end entity; architecture arc of detect_rising_edge is begin process(clk, rst_n, d) begin if (rst_n = '0') then q <= '0'; elsif rising_edge(clk) then if rising_edge(d) then q <= '1'; else q <= '0'; end if; end if; end process; end arc;
果然, 他的process真的出了問題了
首先, 他希望用一個process來完成兩個d-ff的功能
基本上是不太可能的(應該說是完全不可能)
因為在一個VHDL的process中
它的基本架構是長成下面這個樣子的:
沒錯, 這裡可以看得出來
觸發源只有一個clk
因此在elsif的地方呢
蕭兄用了兩次rising_edge
這個很明顯無法產生正確的結果
因為VHDL會只認第一個rising_edge
下一個rising_edge, 它會認定條件不成立
(本來就沒有的東西, 難不成要叫娘子出來看上帝???)
所以當然只跑 q <= '0' 這個敘述
那麼正確的該怎麼寫呢
我們先來看一下蕭兄的Verilog程式吧!!!
(總是要給人家一點面子, 但面子也是人家湊上來......丟的......)
reg q; reg d_d1; always@(posedge clk or negedge rst_n) if (~rst_n) d_d1 <= 1'b0; else d_d1 <= d; always@(posedge clk or negedge rst_n) if (~rst_n) q <= 1'b0; else ({d_d1, d} == 2'b01) q <= 1'b1; else q <= 1'b0;
不愧是蕭兄, 連Verilog都寫得很簡潔
那麼VHDL呢??
請看小弟的寫法
architecture arc of detect_rising_edge is signal d_d1 :std_logic; signal d_con:std_logic; begin process(clk, rst_n) begin if(rst_n = '0') then d_d1 <= '0'; elsif rising_edge(clk) then d_d1 <= d; end if; end process; d_con <= (not d_d1) and d; process(clk, rst_n, d_con) begin if(rst_n = '0') then q <= '0'; elsif rising_edge(clk) then q <= d_con; end if; end process; end arc;
沒錯, 就是這樣, 兩個是不是很像呢???
兩個always對應到兩個process
再根據先前所提的理論
來驗證一下RTL吧(使用工具: Xilinx ISE 10.1)
再加上模擬結果
是不是跟蕭兄的結果一模一樣呢???
其實蕭兄原先的想法是
不想用到與Verilog的coding style去寫VHDL
而我也曾試著改過他的code
發現真的不行
我才深入思考數位邏輯內的架構是如何
另外
在simulation時也發現一個好玩的問題
若剛好d的上升源離clk的上升源太近的話
delay的效果就不見囉
這是因為在第二個D-FF前只有一個clock cycle delay
通常這類的設計會使用兩個以上
如下圖
很明顯的, input訊號需要先被同步後再進行delay
這樣才能確保正確的判斷所輸入的資料是否有產生變化
(上圖為雙邊檢測)
以上
是回答蕭兄的"問題1"......
其他的問題會陸續補上解答
(這小子問題還真多 = = )
沒有留言:
張貼留言