时序反馈移位寄存器建模
- 1,阻塞赋值实现的LFSR,实际上并不具有LFSR功能
- 1.1.1,RTL设计,阻塞赋值
- 1.1.2,tb测试代码
- 1.1.3,波形仿真输出,SIM输出,没实现LFSR
- 1.2.1,RTL设计,拼凑型实现LFSR功能
- 1.2.2,sim输出波形实现
- 2,用非阻塞赋值实现LSFR功能
- 2.1.1,RTL设计,非阻塞赋值
- 2.1.2,测试代码tb
- 2.1.3,波形功能实现,LFSR
- 2.2.1,RTL代码设计,拼凑型实现LFSR,建议
- 2.2.2,测试代码,tb
- 2.2.3,波形功能实现,LFSR
阻塞和非阻塞赋值语句的区别: 1,阻塞赋值,顺序执行; 2,非阻塞赋值,并行执行。
原则1,:时序电路建模时,用非阻塞赋值;
原则2:锁存器电路建模时,用非阻塞赋值。
前述:
在描述时序逻辑时,必须养成使用非阻塞赋值的习惯(无论用多个always块或单个always块来描述时)。
如果使用阻塞赋值语句,在较为复杂的多个always块中设计项目,稍不注意就可能会出现竞争冒险,或者功能错误,使设计的电路出现问题。
1,阻塞赋值实现的LFSR,实际上并不具有LFSR功能
线性反馈移位寄存器(LFSR),是带反馈回路的时序逻辑。
反馈回路给习惯于顺序阻塞赋值描述时序逻辑的设计人员带来了麻烦。
1.1.1,RTL设计,阻塞赋值
//
module lfsrb1(q3, clk, pre_n);
output q3;
input clk, pre_n;
reg q1, q2, q3;
wire n1;
assign n1 = q1 ^ q3;
always@(posedge clk or negedge pre_n)
if(!pre_n) begin
q3 = 1'b1;
q2 = 1'b1;
q1 = 1'b1;
end
else begin
q3 = q2;
q2 = n1;
q1 = q3;
end
endmodule
除非使用中间暂存变量,否则上例所示的赋值是不可能实现反馈逻辑的。
1.1.2,tb测试代码
module test_lfsrb1;
reg clk, pre_n;
wire q3;
lfsrb1 u1_lfsrb1(
.q3 (q3 ),
.clk (clk ),
.pre_n (pre_n )
);
always #5 clk = ~clk; // T = 10
initial begin
clk = 1'b1;
pre_n = 1'b0;
#100
pre_n = 1'b1;
end
endmodule
1.1.3,波形仿真输出,SIM输出,没实现LFSR
1.2.1,RTL设计,拼凑型实现LFSR功能
module lfsrb1(q3, clk, pre_n);
output q3;
input clk, pre_n;
reg q1, q2, q3;
wire n1;
assign n1 = q1 ^ q3;
always@(posedge clk or negedge pre_n)
if(!pre_n) begin
{q3, q2, q1} = 3'b111;
end
else begin
{q3, q2, q1} = {q2, (q1^q3), q3};
end
endmodule
1.2.2,sim输出波形实现
备注:用阻塞赋值描述的线性反馈移位寄存器,其功能虽然正确,但不建议使用。
2,用非阻塞赋值实现LSFR功能
2.1.1,RTL设计,非阻塞赋值
mmodule lfsrb1(q3, clk, pre_n);
output q3;
input clk, pre_n;
reg q1, q2, q3;
wire n1;
assign n1 = q1 ^ q3;
always@(posedge clk or negedge pre_n)
if(!pre_n) begin
q3 <= 1'b1;
q2 <= 1'b1;
q1 <= 1'b1;
end
else begin
q3 <= q2;
q2 <= n1;
q1 <= q3;
end
endmodule
2.1.2,测试代码tb
module test_lfsrb1;
reg clk, pre_n;
wire q3;
lfsrb1 u1_lfsrb1(
.q3 (q3 ),
.clk (clk ),
.pre_n (pre_n )
);
always #5 clk = ~clk; // T = 10
initial begin
clk = 1'b1;
pre_n = 1'b0;
#100
pre_n = 1'b1;
end
endmodule
2.1.3,波形功能实现,LFSR
2.2.1,RTL代码设计,拼凑型实现LFSR,建议
module lfsrb1(q3, clk, pre_n);
output q3;
input clk, pre_n;
reg q1, q2, q3;
// wire n1;
// assign n1 = q1 ^ q3;
always@(posedge clk or negedge pre_n)
if(!pre_n) begin
{q3, q2, q1} <= 3'b111;
end
else begin
{q3, q2, q1} <= {q2, (q1^q3), q3};
end
endmodule
2.2.2,测试代码,tb
module test_lfsrb1;
reg clk, pre_n;
wire q3;
lfsrb1 u1_lfsrb1(
.q3 (q3 ),
.clk (clk ),
.pre_n (pre_n )
);
always #5 clk = ~clk; // T = 10
initial begin
clk = 1'b1;
pre_n = 1'b0;
#100
pre_n = 1'b1;
end
endmodule