2010-08-19 94 views
4

我對HDL語言很陌生。我有一個關於如何編程移位寄存器的問題。 (我知道我轉向另一個方向)。爲什麼這本書使用wire[N-1:0] r_next?我的實施有什麼缺點? 感謝移位寄存器Verilog

我第一次嘗試是如下

module lesson04#(parameter N=8)(
    input wire clk, reset, 
    input wire data, 
    output wire out 
); 

reg [N-1: 0] r_reg; 


always @(posedge clk or negedge reset) 
begin 
    if(!reset) 
     r_reg =0; 
    else 
     r_reg[0]=data; 
     r_reg = r_reg<<1; 
end 

assign out =r_reg[N-1]; 
endmodule 

但書中給出:

module lesson04#(parameter N=8)(
    input wire clk, reset, 
    input wire data, 
    output wire out 
); 

reg [N-1: 0] r_reg; 
wire[N-1:0] r_next; 

always @(posedge clk or negedge reset) 
begin 
    if(!reset) 
     r_reg =0; 
    else 
     r_reg <= r_next; 
end 

assign r_next= {data, r_reg[N-1:1]}; 
assign out =r_reg[N-1]; 
endmodule 

回答

6

首先,不要忘記你的begin - 周圍的代碼段end S:

else begin 
    r_reg[0]=data; 
    r_reg = r_reg<<1; 
end 

沒有這個,onl y r_reg[0]=data將在if聲明的else條款中。這可以工作,但由於順序邏輯描述中的阻塞語句而被認爲是不好的樣式...其次,對於順序塊的建模,使用非阻塞賦值(<=)或者您的計算可能會「跌倒」(谷歌非阻塞與阻止更多信息)。你的例子可能工作得很好(你是否在模擬器中嘗試過)?但是如果事情變得更加複雜,並且添加更多變量,事情可能會破壞。

always @(posedge clk or negedge reset) 
begin 
    if(!reset) 
     r_reg <= 0; 
    else begin // This is horrible! Don't write code like this! 
     r_reg[0] = data;  // blocking 
     r_reg <= r_reg<<1; // non-blocking 
    end 
end 

由於上述原因,它有時被建議組合邏輯被從時序邏輯分開,這樣就可以寫非阻塞賦值給在連續塊的寄存器,並且在組合塊阻塞和從來不用擔心調度。

要以這種方式進行編碼,您需要計算下一個輸出應該使用當前狀態,因此在答案中使用r_next總線。如果所有觸發器都以這種方式與周圍的組合邏輯分離,我認爲它也傾向於幫助綜合工具。另外,如果您的重置爲低電平有效(例如LOW重置),則應將其命名爲或reset_n

3

你的實現產生了與本書完全不同的輸出。您應該通過構建一個簡單的測試臺來驅動您的輸入並運行仿真來證明這一點。您將看到,本書的輸出將輸入數據移動一個時鐘週期,而您的輸出通過八個時鐘週期移動輸入數據。

順便說一句,你縮進了你的always塊,我被引導認爲它不是你想要的。這是你的塊是如何真正的行爲:

always @(posedge clk or negedge reset) 
begin 
    if(!reset) begin 
     r_reg =0; 
    end else begin 
     r_reg[0]=data; 
    end 
    r_reg = r_reg<<1; 
end 

我總是明確地使用begin/end關鍵字if/else語句來避免這種混亂。

它的模擬方式r_reg始終爲0,因爲您將第一個作業(r_reg[0]=data;)與第二個作業(r_reg = r_reg<<1;)打成一體。另一個區別是,本書將data分配給移位寄存器的MSB,但將其分配給LSB。

如果你使用體面的短線和綜合工具,你可能會得到一堆警告代碼。這會提醒您進行一些更改。

+0

'if/else's中的'begin/end'很快成爲反射! – Marty 2010-08-19 13:28:26

+0

我同意。實際上,我甚至在編輯器中爲此創建了一個宏。 – toolic 2010-08-19 13:30:20

+0

那麼這本書的答案是'錯誤',不是嗎?如果只想延遲一個時鐘週期,爲什麼會有8個觸發器? ......除非是成績單中的拼寫錯誤(畢竟有copypasta證據).. – Marty 2010-08-19 18:09:42