在 Verilog 行为建模中复制寄存器值
Copying register value in Verilog behavioral modelling
我正在使用行为建模方法在 Verilog 中设计加密模块,但我无法将寄存器值传递到 Data_out 端口。我在 Data_out 端口复制寄存器 p 值时犯了一点错误。还附有测试平台。模块的预期输出应该是 Data_out = (Data_in + Key) MOD 26. 但由于系统问题,我们不能使用 % 运算符。
你的回答对我很有价值。
module encription(Start,Clk,Reset,Data_In, Key,Data_out,Done);
parameter M='d26;
parameter S0=0, S1=1, S2= 2;
input Clk,Reset,Start;
input [4:0] Data_In,Key;
output reg [4:0] Data_out;
output reg Done;
reg [1:0] state;
reg [4:0] p,q,r,s;
always @ (posedge Clk)
begin
r <= Data_In;
s <= Key;
end
always @ (posedge Clk )
begin
if(Reset=='b0)
begin
Done <= 1'b0;
p <= M;
end
else if (Reset == 'b1)
case (state)
S0:
if (Start) begin
q <= r + s;
state <= S1;
end
S1:
if (p >= q) begin
p <= p - q;
state <= S2;
end
S2:
begin
Data_out <= p;
Done <= 1'b1;
Done <= 1'b0;
end
default:
state <= S0;
endcase
end
endmodule
module Encryption_tb();
reg Clk,Reset,Start;
reg [4:0] Data_In,Key;
wire [4:0] Data_out;
wire [4:0] q;
wire Done;
encription DUT(Start,Clk,Reset,Data_In, Key,Data_out,Done);
initial
begin
Clk = 0;
forever #5 Clk=~Clk;
end
initial
begin
#10 Start = 'b1; Data_In = 'b000111; Key = 'b01110;
#10 Start = 'b1; Data_In = 'b000101; Key = 'b01100;
#10 Start = 'b1; Data_In = 'b000001; Key = 'b00110;
#10 Reset = 'b1; Start = 'b1;
//#10 Reset = 'b0;
#10 Start = 'b1; Data_In = 'b000111; Key = 'b01110;
#10 Start = 'b1; Data_In = 'b000101; Key = 'b01100;
#10 Start = 'b1; Data_In = 'b000001; Key = 'b00110;
#10 $finish;
end
endmodule
我看到了几个问题。
在你的状态机中退出 S1 的唯一方法是 if "if (p >= q)"。如果 p 已经小于 Q,你将永远停留在那个状态。
在您的测试平台中,您为您的状态提供了两次启动之间的时间
机器到 运行.
几点建议:
更好的缩进可以更容易地查看代码块中的内容:例如:
S1:
if (p >= q) begin
p <= p - q;
state <= S2;
end
在您的测试台中,不要使用#10 来定义刺激序列,而是使用@(posedge Clk),这样,如果您的时钟频率发生变化或在 TB 中使用了其他长度延迟,事情仍然会发生变化跟上时钟。
使用@(Done)等待结果。
我也很好奇,你用的什么综合工具不支持%?
这不需要状态机,只需要一些触发器。
右图:
module encription(Start,Clk,Reset,Data_In, Key,Data_out,Done);
parameter M='d26;
parameter S0=0, S1=1, S2= 2;
input Clk,Reset,Start;
input [4:0] Data_In,Key;
output reg [4:0] Data_out;
output reg Done;
reg [6:0] sum;
assign sum = Data_In + Key;
always @ (posedge Clk )
begin
if(Reset=='b1)
begin
Data_out <= 0;
Done <= 0;
end
else
begin
if(sum < M)
Data_out <= sum;
else
if(sum < 2*M)
Data_out <= sum - M;
else
Data_out <= sum - 2*M ;
Done <= Start;
end
end
endmodule
具有有意义向量的测试平台:
module Encryption_tb();
reg Clk,Reset,Start;
reg [4:0] Data_In,Key;
wire [4:0] Data_out;
wire [4:0] q;
wire Done;
encription DUT(Start,Clk,Reset,Data_In, Key,Data_out,Done);
initial
begin
Clk = 0;
forever #5 Clk=~Clk;
end
initial
begin :initial_block
$monitor("Data_In = %d,Key = %d, Data_out = %d",Data_In,Key,Data_out);
Reset = 1;
#20 Reset = 0;
#10;
#1;
Start = 1;
for(int i = 0; i < 30; i++)
begin
@ (posedge Clk);
#1;
Key = i;
Data_In = i;
end
#10 $finish;
end :initial_block
initial
begin
$dumpfile("dump.vcd");
$dumpvars;
end
endmodule
一些输出(请注意,由于触发器,答案延迟了 1 个时钟)
Data_In = 0,Key = 0, Data_out = 0
Data_In = 1,Key = 1, Data_out = 0
Data_In = 1,Key = 1, Data_out = 2
Data_In = 2,Key = 2, Data_out = 2
Data_In = 2,Key = 2, Data_out = 4
Data_In = 3,Key = 3, Data_out = 4
Data_In = 3,Key = 3, Data_out = 6
Data_In = 4,Key = 4, Data_out = 6
Data_In = 4,Key = 4, Data_out = 8
Data_In = 5,Key = 5, Data_out = 8
Data_In = 5,Key = 5, Data_out = 10
Data_In = 6,Key = 6, Data_out = 10
Data_In = 6,Key = 6, Data_out = 12
Data_In = 7,Key = 7, Data_out = 12
Data_In = 7,Key = 7, Data_out = 14
Data_In = 8,Key = 8, Data_out = 14
Data_In = 8,Key = 8, Data_out = 16
Data_In = 9,Key = 9, Data_out = 16
Data_In = 9,Key = 9, Data_out = 18
Data_In = 10,Key = 10, Data_out = 18
Data_In = 10,Key = 10, Data_out = 20
Data_In = 11,Key = 11, Data_out = 20
Data_In = 11,Key = 11, Data_out = 22
Data_In = 12,Key = 12, Data_out = 22
Data_In = 12,Key = 12, Data_out = 24
Data_In = 13,Key = 13, Data_out = 24
Data_In = 13,Key = 13, Data_out = 0
Data_In = 14,Key = 14, Data_out = 0
Data_In = 14,Key = 14, Data_out = 2
Data_In = 15,Key = 15, Data_out = 2
Data_In = 15,Key = 15, Data_out = 4
Data_In = 16,Key = 16, Data_out = 4
Data_In = 16,Key = 16, Data_out = 6
Data_In = 17,Key = 17, Data_out = 6
Data_In = 17,Key = 17, Data_out = 8
Data_In = 18,Key = 18, Data_out = 8
我正在使用行为建模方法在 Verilog 中设计加密模块,但我无法将寄存器值传递到 Data_out 端口。我在 Data_out 端口复制寄存器 p 值时犯了一点错误。还附有测试平台。模块的预期输出应该是 Data_out = (Data_in + Key) MOD 26. 但由于系统问题,我们不能使用 % 运算符。 你的回答对我很有价值。
module encription(Start,Clk,Reset,Data_In, Key,Data_out,Done);
parameter M='d26;
parameter S0=0, S1=1, S2= 2;
input Clk,Reset,Start;
input [4:0] Data_In,Key;
output reg [4:0] Data_out;
output reg Done;
reg [1:0] state;
reg [4:0] p,q,r,s;
always @ (posedge Clk)
begin
r <= Data_In;
s <= Key;
end
always @ (posedge Clk )
begin
if(Reset=='b0)
begin
Done <= 1'b0;
p <= M;
end
else if (Reset == 'b1)
case (state)
S0:
if (Start) begin
q <= r + s;
state <= S1;
end
S1:
if (p >= q) begin
p <= p - q;
state <= S2;
end
S2:
begin
Data_out <= p;
Done <= 1'b1;
Done <= 1'b0;
end
default:
state <= S0;
endcase
end
endmodule
module Encryption_tb();
reg Clk,Reset,Start;
reg [4:0] Data_In,Key;
wire [4:0] Data_out;
wire [4:0] q;
wire Done;
encription DUT(Start,Clk,Reset,Data_In, Key,Data_out,Done);
initial
begin
Clk = 0;
forever #5 Clk=~Clk;
end
initial
begin
#10 Start = 'b1; Data_In = 'b000111; Key = 'b01110;
#10 Start = 'b1; Data_In = 'b000101; Key = 'b01100;
#10 Start = 'b1; Data_In = 'b000001; Key = 'b00110;
#10 Reset = 'b1; Start = 'b1;
//#10 Reset = 'b0;
#10 Start = 'b1; Data_In = 'b000111; Key = 'b01110;
#10 Start = 'b1; Data_In = 'b000101; Key = 'b01100;
#10 Start = 'b1; Data_In = 'b000001; Key = 'b00110;
#10 $finish;
end
endmodule
我看到了几个问题。
在你的状态机中退出 S1 的唯一方法是 if "if (p >= q)"。如果 p 已经小于 Q,你将永远停留在那个状态。
在您的测试平台中,您为您的状态提供了两次启动之间的时间 机器到 运行.
几点建议: 更好的缩进可以更容易地查看代码块中的内容:例如:
S1:
if (p >= q) begin
p <= p - q;
state <= S2;
end
在您的测试台中,不要使用#10 来定义刺激序列,而是使用@(posedge Clk),这样,如果您的时钟频率发生变化或在 TB 中使用了其他长度延迟,事情仍然会发生变化跟上时钟。 使用@(Done)等待结果。
我也很好奇,你用的什么综合工具不支持%?
这不需要状态机,只需要一些触发器。
右图:
module encription(Start,Clk,Reset,Data_In, Key,Data_out,Done);
parameter M='d26;
parameter S0=0, S1=1, S2= 2;
input Clk,Reset,Start;
input [4:0] Data_In,Key;
output reg [4:0] Data_out;
output reg Done;
reg [6:0] sum;
assign sum = Data_In + Key;
always @ (posedge Clk )
begin
if(Reset=='b1)
begin
Data_out <= 0;
Done <= 0;
end
else
begin
if(sum < M)
Data_out <= sum;
else
if(sum < 2*M)
Data_out <= sum - M;
else
Data_out <= sum - 2*M ;
Done <= Start;
end
end
endmodule
具有有意义向量的测试平台:
module Encryption_tb();
reg Clk,Reset,Start;
reg [4:0] Data_In,Key;
wire [4:0] Data_out;
wire [4:0] q;
wire Done;
encription DUT(Start,Clk,Reset,Data_In, Key,Data_out,Done);
initial
begin
Clk = 0;
forever #5 Clk=~Clk;
end
initial
begin :initial_block
$monitor("Data_In = %d,Key = %d, Data_out = %d",Data_In,Key,Data_out);
Reset = 1;
#20 Reset = 0;
#10;
#1;
Start = 1;
for(int i = 0; i < 30; i++)
begin
@ (posedge Clk);
#1;
Key = i;
Data_In = i;
end
#10 $finish;
end :initial_block
initial
begin
$dumpfile("dump.vcd");
$dumpvars;
end
endmodule
一些输出(请注意,由于触发器,答案延迟了 1 个时钟)
Data_In = 0,Key = 0, Data_out = 0
Data_In = 1,Key = 1, Data_out = 0
Data_In = 1,Key = 1, Data_out = 2
Data_In = 2,Key = 2, Data_out = 2
Data_In = 2,Key = 2, Data_out = 4
Data_In = 3,Key = 3, Data_out = 4
Data_In = 3,Key = 3, Data_out = 6
Data_In = 4,Key = 4, Data_out = 6
Data_In = 4,Key = 4, Data_out = 8
Data_In = 5,Key = 5, Data_out = 8
Data_In = 5,Key = 5, Data_out = 10
Data_In = 6,Key = 6, Data_out = 10
Data_In = 6,Key = 6, Data_out = 12
Data_In = 7,Key = 7, Data_out = 12
Data_In = 7,Key = 7, Data_out = 14
Data_In = 8,Key = 8, Data_out = 14
Data_In = 8,Key = 8, Data_out = 16
Data_In = 9,Key = 9, Data_out = 16
Data_In = 9,Key = 9, Data_out = 18
Data_In = 10,Key = 10, Data_out = 18
Data_In = 10,Key = 10, Data_out = 20
Data_In = 11,Key = 11, Data_out = 20
Data_In = 11,Key = 11, Data_out = 22
Data_In = 12,Key = 12, Data_out = 22
Data_In = 12,Key = 12, Data_out = 24
Data_In = 13,Key = 13, Data_out = 24
Data_In = 13,Key = 13, Data_out = 0
Data_In = 14,Key = 14, Data_out = 0
Data_In = 14,Key = 14, Data_out = 2
Data_In = 15,Key = 15, Data_out = 2
Data_In = 15,Key = 15, Data_out = 4
Data_In = 16,Key = 16, Data_out = 4
Data_In = 16,Key = 16, Data_out = 6
Data_In = 17,Key = 17, Data_out = 6
Data_In = 17,Key = 17, Data_out = 8
Data_In = 18,Key = 18, Data_out = 8