2010-08-19 204 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