0

我正在使用 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

先感谢您!

4

2 回答 2

1

您的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));
于 2013-11-19T03:50:42.133 回答
1

除了 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)驱动同一个寄存器。这会让你的编译器发脾气。

于 2013-11-19T15:13:08.893 回答