我正在尝试模拟这个模块,但在模拟过程中所有变量都是x。为什么? 变量定义和使用有什么问题吗? 我是verilog的新手,我不确定我对变量的用法是否正确.. 这是模块和测试平台:
module viterbi_decoder(
clock , // Clock input of the design
reset , // active high, synchronous Reset input
in_vector ,
out_vector
);
//inputs
input clock;
input reset;
input [7:0]in_vector;
//outputs
output [7:0] out_vector;
reg [7:0] out_vector;
//local variables
integer index;
integer row00[4:0];
integer row01[4:0];
integer row10[4:0];
integer row11[4:0];
integer prev_row00[4:0];
integer prev_row01[4:0];
integer prev_row10[4:0];
integer prev_row11[4:0];
integer who;
integer from;
integer mini;
integer ham_dist_1;
integer ham_dist_2;
reg in[1:0];
always @ (posedge clock)
begin
if (reset)
begin
//reset device
row00[0] <= 3;
row01[0] <= 3;
row10[0] <= 3;
row11[0] <= 3;
end
else
begin
row00[0] <= 3;
row01[0] <= 3;
row10[0] <= 3;
row11[0] <= 3;
for (index=0; index < 8; index = index + 2)
//mini([n-1,0],[n-1,1])
ham_dist_1 <= in_vector[index] ^ 0 + in_vector[index + 1] ^ 0 + row00[(index / 2)];
ham_dist_2 <= in_vector[index] ^ 1 + in_vector[index + 1] ^ 1 + row01[(index / 2)];
if (ham_dist_1 > ham_dist_2 )
begin
row00[index / 2 + 1] <= ham_dist_1;
prev_row00[index / 2 + 1] <= 0;
end
else
begin
row00[index / 2 + 1] <= ham_dist_2;
prev_row00[index / 2 + 1] <= 1;
end
ham_dist_1 <= in_vector[index] ^ 1 + in_vector[index + 1] ^ 0 + row10[(index / 2)];
ham_dist_2 <= in_vector[index] ^ 0 + in_vector[index + 1] ^ 1 + row11[(index / 2)];
if (ham_dist_1 > ham_dist_2 )
begin
row01[index / 2 + 1] <= ham_dist_1;
prev_row01[index / 2 + 1] <= 2;
end
else
begin
row01[index / 2 + 1] <= ham_dist_2;
prev_row01[index / 2 + 1] <= 3;
end
ham_dist_1 <= in_vector[index] ^ 0 + in_vector[index + 1] ^ 0 + row00[(index / 2)];
ham_dist_2 <= in_vector[index] ^ 1 + in_vector[index + 1] ^ 1 + row01[(index / 2)];
if (ham_dist_1 > ham_dist_2 )
begin
row10[index / 2 + 1] <= ham_dist_1;
prev_row10[index / 2 + 1] <= 0;
end
else
begin
row10[index / 2 + 1] <= ham_dist_2;
prev_row10[index / 2 + 1] <= 1;
end
ham_dist_1 <= in_vector[index] ^ 0 + in_vector[index + 1] ^ 1 + row10[(index / 2)];
ham_dist_2 <= in_vector[index] ^ 1 + in_vector[index + 1] ^ 0 + row11[(index / 2)];
if (ham_dist_1 > ham_dist_2 )
begin
row11[index / 2 + 1] <= ham_dist_1;
prev_row11[index / 2 + 1] <= 2;
end
else
begin
row11[index / 2 + 1] <= ham_dist_2;
prev_row11[index / 2 + 1] <= 3;
end
//trace back algorithm
who <= 00;
from <= prev_row00[4];
mini <= row00[4];
if (row01[4] < mini)
begin
who <= 01;
from <= prev_row01[4];
mini <= row01[4];
end
if (row10[4] < mini)
begin
who <= 10;
from <= prev_row10[4];
mini <= row10[4];
end
if (row11[4] < mini)
begin
who <= 11;
from <= prev_row11[4];
mini <= row11[4];
end
for (index=3; index > 0; index = index - 1 )
begin
if (who == 00 && from == 00)
begin
out_vector[(index + 1) * 2] <= 0;
out_vector[((index + 1) * 2 )- 1] <= 0;
who <= 00;
from <= prev_row00[index -1];
end
else if (who == 00 && from == 01)
begin
out_vector[(index + 1) * 2] <= 1;
out_vector[((index + 1) * 2 )- 1] <= 1;
who <= 01;
from <= prev_row01[index -1];
end
else if (who == 01 && from == 10)
begin
out_vector[(index + 1) * 2] <= 1;
out_vector[((index + 1) * 2 )- 1] <= 0;
who <= 10;
from <= prev_row10[index -1];
end
else if (who == 01 && from == 11)
begin
out_vector[(index + 1) * 2] <= 0;
out_vector[((index + 1) * 2 )- 1] <= 1;
who <= 11;
from <= prev_row11[index -1];
end
else if (who == 10 && from == 00)
begin
out_vector[(index + 1) * 2] <= 1;
out_vector[((index + 1) * 2 )- 1] <= 1;
who <= 00;
from <= prev_row00[index -1];
end
else if (who == 10 && from == 01)
begin
out_vector[(index + 1) * 2] <= 0;
out_vector[((index + 1) * 2 )- 1] <= 0;
who <= 01;
from <= prev_row01[index -1];
end
else if (who == 11 && from == 10)
begin
out_vector[(index + 1) * 2] <= 0;
out_vector[((index + 1) * 2 )- 1] <= 1;
who <= 10;
from <= prev_row10[index -1];
end
else if (who == 11 && from == 11)
begin
out_vector[(index + 1) * 2] <= 1;
out_vector[((index + 1) * 2 )- 1] <= 0;
who <= 11;
from <= prev_row11[index -1];
end
end
end
end
endmodule
`timescale 1ns /1ps
module Testbench;
reg clock_t;
reg reset_t;
reg [7:0] in_vector_t;
wire [7:0] out_vector_t;
viterbi_decoder viterbi_1(.clock(clock_t), .reset(reset_t), .in_vector(in_vector_t), .out_vector(out_vector_t));
initial begin
clock_t = 0;
reset_t = 0;
end
always #10000 clock_t = ~clock_t;
always@(posedge clock_t)
begin
//case 0
in_vector_t <= 00110101; // <= 1; reset_t <= 0;
#5 $display("Result_t = %b", out_vector_t);
//case 1
in_vector_t <= 00001111; //clock_t <= 1; reset_t <= 0;
#5 $display("Result_t = %b", out_vector_t);
//case 2
in_vector_t <= 00010101; //clock_t <= 1; reset_t <= 0;
#5 $display("Result_t = %b", out_vector_t);
//case 3
in_vector_t <= 00101100; //clock_t <= 1; reset_t <= 0;
#5 $display("Result_t = %b", out_vector_t);
//case 4
in_vector_t <= 00000000; //clock_t <= 1; reset_t <= 0;
#5 $display("Result_t = %b", out_vector_t);
end
endmodule
答案 0 :(得分:1)
首先,您的测试台需要改进。时钟非常慢,dut只会在任何时钟边沿看到in_vector_t <= 00000000;
。我建议您更改与时钟边缘相关的in_vector_t
。此外,由于您有一个自由运行的时钟,您需要使用$finish
结束模拟。例如:
always #5 clock_t = ~clock_t;
initial begin
$monitor("Result_t = %b", out_vector_t);
@(posedge clock_t) in_vector_t <= 8'b00110101; //case 0
@(posedge clock_t) in_vector_t <= 8'b00001111; //case 1
@(posedge clock_t) in_vector_t <= 8'b00010101; //case 2
@(posedge clock_t) in_vector_t <= 8'b00101100; //case 3
@(posedge clock_t) in_vector_t <= 8'b00000000; //case 4
@(posedge clock_t);
#5 $finish; // end simulation
end
在您的设计中,您可能会将两位值设置/比较为10
或11
。这些值在十进制十和十一。您需要指定宽度和基本类型,I.E。 2'b10
或2'b11
。您的测试台也是如此; 00001111
是十进制一千一百一十一,8'b00001111
是十进制十五。
您在时钟始终块内使用非阻塞(<=
)。这是对的。问题是您的代码似乎取决于最近更新的值。通过非阻塞分配,寄存器在时间步结束之前不会获得新值。采样/比较该值的任何内容都将在此之前看到旧值。在这种情况下,您需要将块拆分为两个始终块:一个使用非阻塞(<=
)同步,一个使用阻塞(=
)。不知道你的完整预期逻辑我会给你一个入门的模板:
always @* begin : comb_logic__calc_next
// defaults (constants or flops)
next_example1 = 8'h00; // constant
next_example2 = example2;// flop
/* algorithms for here
.... made-up example * /
for (index = 0; index<8; index=index+1) begin
if (input_bus[index]==1'b1) next_example1[index] = 1'b1;
else next_example2[index] = ~next_example2[index];
if (next_example1[index]==example[7-index]) begin
next_example2 = {next_example2[6:0],next_example2[7]};
end
end
end
always @(posedge clock) begin : synchronous_logic__assign_flops
if (reset) begin
// constants only
example1 <= 8'h00;
example2 <= 8'h00;
end
else begin
// assign flops to next value
example1 <= next_example1;
example2 <= next_example2;
end
end
除此之外,您还需要使用波形转储运行模拟。