【发布时间】:2018-12-02 19:44:12
【问题描述】:
我正在尝试在 verilog 中学习有效/就绪的握手。特别是,我有兴趣使用 ready 作为指示数据事务成功的标志(即,ready_in 在valid_out 变高之后变高)。我想用一个非常简单的 Verilog 示例来解释我的问题。我写了一个卷积编码器(代码如下)
module Conv_Encoder_Core(
input wire clk,
input wire reset,
input wire in_bit,
output reg out_A,
output reg out_B,
input wire sleep,
input wire valid_in,
input wire ready_in,
output reg valid_out,
output reg ready_out);
reg [5:0] S;
wire S_A, S_B, clkON;
assign S_A = S[1] ^ S[2] ^ S[4] ^S[5];
assign S_B = S[0] ^ S[1] ^ S[2] ^S[5];
assign clkON = clk & !sleep;
always @(posedge clkON)begin
if (reset) begin
S <=0;
valid_out <=0;
ready_out <=0;
end else if (valid_in) begin
out_A <= in_bit ^ S_A;
out_B <= in_bit ^ S_B;
valid_out <=1;
if (ready_in)begin
S<= S<<1;
S[0] <=in_bit;
ready_out <=1;
end else begin
ready_out <=0;
end
end else begin
valid_out <=0;
ready_out <=0;
end
end
endmodule
我有兴趣使用ready_in 标志作为指示数据out_A 和out_B 被下一个块接收,因此我的块可以通过将ready_out 标志设置为高来接受新数据。我已经为此块编写了一个测试台,但是,我没有得到我期望的结果
`timescale 1 ns/1 ns
module TB_Conv();
reg clk;
//---------------clock generator-----------------------
initial begin
clk = 1'b0;
#5;
clk = 1'b1;
forever begin
#5 clk = ~clk;
end
end
//------------------ dump -----------------------
initial begin
$dumpfile("dumpVCD.vcd");
$dumpvars(10);
end
localparam N_DATA=10;
reg in_bits_vec [0:N_DATA-1];
initial begin
in_bits_vec[0] = 1'b1;
in_bits_vec[1] = 1'b0;
in_bits_vec[2] = 1'b0;
in_bits_vec[3] = 1'b0;
in_bits_vec[4] = 1'b0;
in_bits_vec[5] = 1'b0;
in_bits_vec[6] = 1'b0;
in_bits_vec[7] = 1'b0;
in_bits_vec[8] = 1'b0;
in_bits_vec[9] = 1'b1;
end
reg in_bit, ready_in,reset, valid_in;
Conv_Encoder_Core UUT(.clk(clk),
.reset(reset),
.in_bit(in_bit),
.out_A(out_A),
.out_B(out_B),
.sleep(1'b0),
.valid_in(valid_in),
.ready_in(ready_in),
.valid_out(valid_out),
.ready_out(ready_out));
//---------------- code starts here -------------------//
reg [3:0] addr;
always @(posedge clk) begin
if (reset)begin
addr<=0;
valid_in <=0;
in_bit <=0;
end else if (addr < 10) begin
in_bit <= in_bits_vec[addr];
valid_in <=1'b1;
if (ready_out) begin
addr <= addr+1'b1;
end
end else begin
in_bit <=0;
valid_in <=0;
end
if (valid_out==1) ready_in <= 1;
else ready_in <= 0;
end
// ----------- reset logic -----------//
reg [3:0] cnt;
initial cnt=0;
always @(negedge clk)begin
if (cnt<5) begin
reset = 1;
cnt=cnt+1;
end else reset =0;
end
initial begin
#1000;
$finish;
end
endmodule
如果您查看输入数据(在 testbech 中),您可以看到它是 1000000000。我期待看到1 通过S 注册如下:
S = 000000 //at beginning
S = 000001 // after ready_out=1
S = 000010
S = 000100
但是,我得到的结果完全不同(请参阅快照)。
我遇到的另一个问题是inbit=1 比我预期的多两个时钟周期。事实上,当ready_out=1 时,我希望看到in_bit 变为零,但这会在两个时钟周期后发生(快照中的黄色光标)。
如果有人能解释我在这个例子中做错了什么,我将不胜感激。
【问题讨论】:
标签: verilog system-verilog hdl