用Verilog实现如下图所示的线性反馈移位寄存器:
The reset should resetthe LFSR to 1
直接写逻辑门的代码
这种写法比较笨拙。
这里寄存器只有5 bits,数量不算多,因此,这种写法还可以接受,如果寄存器的位数更大呢,比如64bit,甚至128bit,那这种写法就显得非常繁琐了。
module top_module(input clk,input reset, // Active-high synchronous reset to 5'h1output [4:0] q); always@(posedge clk) beginif(reset)q <= 5'h1;else beginq[4] <= 1'b0 ^ q[0];q[3] <= q[4];q[2] <= q[3] ^ q[0];q[1] <= q[2];q[0] <= q[1];endendendmodule
更优的写法
下述这种写法写起来更为简单,尤其是当移位寄存器的位数非常多的时候,优势更为明显。因为LFSR即使位数很多,但是,有反馈的位数并不会太多,下述代码中组合逻辑always模块的代码量仅仅取决于有反馈的位数。
module top_module(input clk,input reset,output reg [4:0] q);reg [4:0] q_next; // q_next is not a register// Convenience: Create a combinational block of logic that computes// what the next value should be. // Combinational always block: Use blocking assignments.always @(*) beginq_next = q[4:1]; // Shift all the bits. This is incorrect for q_next[4] and q_next[2]//向右移一位,高位自动填充0,因此,只写了q[4:1]q_next[4] = q[0]; // Give q_next[4] and q_next[2] their correct assignments//0与x异或,得到的结果是x本身q_next[2] = q[3] ^ q[0];end// This is just a set of DFFs. I chose to compute the connections between the// DFFs above in its own combinational always block, but you can combine them if you wish.// You'll get the same circuit either way.// Edge-triggered always block: Use non-blocking assignments.always @(posedge clk) beginif (reset)q <= 5'h1;elseq <= q_next;endendmodule