我正在使用Altera DE2开发板,我想读取开关上的输入。这存储在寄存器中。根据计数器,这些寄存器递增。然后,寄存器应该被输出到被认为是B2D转换器的七段显示器。但是我不能将寄存器传递给函数。
wire [26:0] Q,Q2,Q3,Q4;
wire [3:0] one,two,three,four;
reg SecInc,MinInc,HrInc;
reg [3:0] M1,M2,H1,H2;
assign one = SW[3:0];
assign two = SW[7:4];
assign three = SW[11:8];
assign four = SW[15:12];
always begin
M1 = SW[3:0];
M2 = SW[7:4];
H1 = SW[11:8];
H2 = SW[15:12];
end
这就是我获取和存储输入的方式。它们来自开关,我们将其用作小时和分钟的二进制表示。基于计数器,我们递增一分钟或一小时寄存器。
//increment seconds from 0 to 60
counter seconds (SecInc,KEY[0],Q2);
defparam seconds.n = 8;
defparam seconds.mod = 60;
always @ (negedge CLOCK_50) begin
if (Q2 >= 60) begin
MinInc = 1;
M1 <= M1 + 1'b1;
if(M1 >= 9) begin
M1 <= 0;
M2 <= M2 + 1'b1;
end
end else begin
MinInc = 0;
end
end
我们想在SSD上显示结果。
hex(M1,HEX4);
hex(M2,HEX5);
hex(H1,HEX6);
hex(H2,HEX7);
问题就在这里。verilog中不允许这样做。我需要一种方法将我的寄存器发送到一个函数,该函数使用一些B2D转换来显示从0到9的数字。
我要说的是,我以前从未正式介绍过verilog,我已经尝试了我能想到的一切。我甚至试图制作一个新的模块,在这个模块中,我会传递一、二、三、四,并让模块递增它们,就像我展示的计数器的Q2一样。非常感谢您的任何建议或帮助!
根据要求,这里是十六进制模块:
module hex(BIN, SSD);
input [15:0] BIN;
output reg [0:6] SSD;
always begin
case(BIN)
0:SSD=7'b0000001;
1:SSD=7'b1001111;
2:SSD=7'b0010010;
3:SSD=7'b0000110;
4:SSD=7'b1001100;
5:SSD=7'b0100100;
6:SSD=7'b0100000;
7:SSD=7'b0001111;
8:SSD=7'b0000000;
9:SSD=7'b0001100;
endcase
end
endmodule
提前谢谢!
您的hex
模块不是函数,它是一个模块,因此必须使用如下实例名进行实例化:
hex digit0(.BIN(M1), .SSD(HEX4));
hex digit1(.BIN(M2), .SSD(HEX5));
hex digit2(.BIN(H1), .SSD(HEX6));
hex digit3(.BIN(H2), .SSD(HEX7));
除了nguthrie是正确的,您需要将十六进制转换器实例化为一个模块之外,您还可以从始终块中的竞争条件中驱动M1
。非阻塞分配将在一个块内同时求值(或基本上同时求值)。这不是一个程序,事情按顺序发生。可能效果更好的是:
always @ (negedge CLOCK_50) begin
if (Q2 >= 60) begin
MinInc = 1;
if (M1 < 9) begin
M1 <= M1 + 1'b1;
end else begin
M1 <= 0;
M2 <= M2 + 1'b1;
end
end else begin
MinInc = 0;
end
end
你也可能会从你对MinInc的屏蔽任务中得到意想不到的结果,但由于我不知道这是从哪里读到的,所以很难知道会发生什么。阅读Verilog中的阻塞(=)与非阻塞(<=)分配。这是该语言中最棘手的概念之一,滥用这两个操作是我见过的90%最卑鄙的错误的原因。编辑:在重读你的问题时,你似乎试图从至少三个地方驾驶M1-4。你真的不可能有一个连续的always begin
块和一个时钟(always @ (negedge clock) begin
)驱动同一个寄存器。这会让你的编译器大发脾气。