我正在尝试做什么:我希望计算从0到十六进制F的数字,并在不同频率的FPGA板上显示这些数字 - 我的主板时钟(CLOCK_50)为50 MHz我希望根据电路板上的两个输入开关(SW [1:0])改变计数的频率/速度。
顶级模块的Verilog代码&时钟分频器模块:
//top level module
module rate_divider (input CLOCK_50, input [1:0] SW, input [1:0] KEY,output [6:0] HEX0);
//Declare parameters that define the # of clock cycles needed to generate an enable pulse
according to the desired frequency.
parameter FREQ_5MHz = 4'd9; //To divide to 5 MHz we need (10-1) cycles,
//since the pulse needs to start at the 9th cycle.
parameter FULL50_MHz = (4'd1); //The CLOCK_50's Frequency.
//Select the desired parameter based on the input switches
reg [3:0] cycles_countdown;
wire enable_display_count;
wire [3:0] selected_freq;
always @(*)
case (SW)
2'b00: cycles_countdown = FULL50_MHz;
2'b01: cycles_countdown = FREQ_5MHz;
default : cycles_countdown = FULL50_MHz;
endcase
assign selected_freq = cycles_countdown;
//wire that is the output of the display_counter and input to the 7 segment
wire [3:0] hex_value;
// instantiate my other modules
clock_divider_enable freq_divider (.d(selected_freq), .clk(CLOCK_50), .reset(KEY[0]),
.enable(enable_display_count));
display_counter count_hex (.enable(enable_display_count), .clk(CLOCK_50), .hex_out(hex_value), .reset(KEY[1]));
hex_decoder HX0 (.hex_digit(hex_value), .segments(HEX0[6:0]));
endmodule
//the clock_divider sub-circuit.
module clock_divider_enable (input [3:0] d, input clk, reset,
output enable);
reg [3:0] q;
always @(posedge clk)
begin
if (!reset || !q)
q <= d;
else
q <= q - 4'd1;
end
assign enable = (q == 4'h0) ? 1'b1 : 1'b0;
endmodule
ModelSim代码:
vlib work
vlog rate_divider.v
vsim rate_divider
log {/*}
add wave {/*}
#initial reset - using KEY[1:0]. Note: active low synchronous reset.
force {CLOCK_50} 1
force {KEY[0]} 0
force {KEY[1]} 0
run 10ns
#choose 5 MHz as the desired frequency - turn SW[0] high.
force {CLOCK_50} 0 0ns, 1 {10ns} -r 20ns
force {KEY[0]} 1
force {KEY[1]} 1
force {SW[0]} 1
force {SW[1]} 0
run 600ns
我面临的问题:
这就是事情 - 当我不使用always块来选择参数,并将所需参数传递给wire_freq线时,我的模拟工作正常 - 我可以看到预期的使能脉冲。
但是,如果我使用always块,则reg cycles_countdown会获得正确的值,但由于某种原因,启用信号只是一条红线。当我选择我的clock_divider_enable模块并将其'q'信号添加到我的波形上时,它也是红色并且没有显示数据,并且对象q“未记录”。因此,我无法调试并弄清楚我的代码究竟是什么问题。
如果有人可以帮助解决模拟问题,而不是仅仅指出我的Verilog代码的问题,那就太棒了,因为我想学习如何有效地使用ModelSim,以便将来调试更容易我
使用的设备:
FPGA:Altera De-1-SoC,Cyclone V芯片
CAD /模拟工具:Altera Quartus II Lite 17.0 + ModelSim入门版
答案 0 :(得分:0)
SW
没有给出初始值,因此它是高Z(如果连接到reg,则为X)。
我猜你在使用参数方法时正在参数化cycles_countdown
。某些模拟器在时间0不会触发@*
。因此,如果参考列表没有变化,则该块可能不会执行;将cycles_countdown
作为初始值(4'hX)。
您可以使用verilog创建测试平台,而不是使用TCL命令驱动测试。此测试平台只能用于模拟,而不能用于合成。
module rate_devider_tb;
reg CLOCK_50;
reg [1:0] SW;
reg [1:0] KEY;
wire [6:0] HEX0;
rate_divider dut( .CLOCK_50(CLOCK_50), .SW(SW), .KEY(KEY), .HEX0(HEX0));
always begin
CLOCK_50 = 1'b1;
#10;
CLOCK_50 = 1'b0;
#10;
end
initial begin
// init input signals
SW <= 2'b01;
KEY <= 2'b00;
// Log file reporting
$monitor("SW:%b KEY:%b HEX0:%h @ %t", SW, KEY, HEX0, $time);
// waveform dumping
$dumpfile("test.vcd");
$dumpvars(0, rate_devider_tb);
wait(CLOCK_50 === 1'b0); // initialization x->1 will trigger an posedge
@(posedge CLOCK_50);
KEY <= 2'b01; // remove reset after SW was sampled
#600; // 600ns assuming timescale is in 1ns steps
$finish();
end