用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'h1
output [4:0] q
);
always@(posedge clk) begin
if(reset)
q <= 5'h1;
else begin
q[4] <= 1'b0 ^ q[0];
q[3] <= q[4];
q[2] <= q[3] ^ q[0];
q[1] <= q[2];
q[0] <= q[1];
end
end
endmodule
更优的写法
下述这种写法写起来更为简单,尤其是当移位寄存器的位数非常多的时候,优势更为明显。因为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 @(*) begin
q_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) begin
if (reset)
q <= 5'h1;
else
q <= q_next;
end
endmodule