【问题标题】:How to pass values between modules in verilog?如何在verilog中的模块之间传递值?
【发布时间】:2022-01-20 20:57:47
【问题描述】:

我正在上硬件课,我们应该在没有太多指导的情况下使用 Verilog 做一个大型项目,但我们被告知它与 C 非常相似。在某些方面可能是这样,但在其他方面则根本不是.例如,我花了几个小时在线查看如何在模块之间传递变量,但无法弄清楚。因此,从 startMod 开始,我尝试调用 dispBinHex 以在十六进制显示的 Altera 板上显示使用 sw[3:2] 和 sw[2:1] 开关之间的加法选择的二进制数。但是我不断收到各种错误,我尝试了很多不同的方法来解决这个问题,但没有运气。最常见的错误是“无法解析 heierchy”,使用下面的代码我得到“输出或输入端口‘out’必须连接到结构网络表达式”。我在网上找到了一些关于按名称或位置连接模块的文章,但那部分仍然超出我的范围。我完全不知道如何使用 Verilog 传递基本模块参数并考虑删除这个类,有人可以阐明如何使用模块,就像我们在 C 中执行函数一样。以下代码都在一个文件中命名为 startMod,它必须是 Verilog 的可综合子集。这是我所拥有的:

module dispBinHex (select, out);
 //Edit: changed input from [3:0] to [1:0]   
      input [1:0] select;
      output reg [6:0] out;

      always @(select)
      begin
        out = 7'b1000000;
          case (select)
            4'b0000: out = 7'b1000000;  // 0
            4'b0001: out = 7'b1111001;  // 1
            4'b0010: out = 7'b0100100;  // 2
          endcase 
      end
    endmodule

    module startMod( 
    input [9:0] sw,
    input [3:0] key, 
    input clock,
    output [9:0] ledr, 
    output [7:0] ledg, 
    output reg [6:0] hex
    );

    integer i;
    reg [3:0] switch;
    switch = sw[3:2] + sw[2:1]; 

/*
    Edit: I replaced the code below until ***********************     
        if (sw[0] == 1'b0)
                begin
                    case (switch)
                        4'b0000:
                            begin
                                dispBinHex BH(.select(switch), .out(hex0)); 
                            end
                        4'b0001: 
                            begin
                                dispBinHex BH(.select(switch), .out(hex0)); 
                            end
                        4'b0010: 
                            begin
                                dispBinHex BH(.select(switch), .out(hex0)); 
                            end
                        4'b0010: 
                            begin
                                dispBinHex BH(.select(switch), .out(hex0));                     
                            end
                  endcase
              end
    ***************************************************
*/
    // with this code

              reg [1:0] switch;

              if (sw[0] == 1'b0)
              begin
                  switch = sw[4:3]+sw[2:1];
                   dispBinHex BH(.select(switch), .out(hex0));
              end
        endmodule

但是我现在得到的错误信息是:

Error (10170): Verilog HDL syntax error at L2C227.v(73) near text "BH";  expecting "<=", or "="

【问题讨论】:

  • 请发布您遇到的错误。此外,仅发布来自综合的警告(因为编译会给您带来数百个可忽略的警告)

标签: function module verilog


【解决方案1】:

我建议您阅读Verilog in a day。由于 verilog 与 C 不同,因此某些语法是相同的,但语言的工作方式却不同。它毕竟是一种硬件描述语言。

变量不在模块之间传递,您描述的是物理连接它们的电线。

当您进入Control Statments 部分时,它们看起来很像 C,但它们必须包含在一个块中。您可以:

always @(posedge clk) // Describes a flip-flop behaviour
always @*             // Describes combinatorial hardware

您还可以使用initial,这对于测试台很有用,因为它只在开始时运行一次。

从这里你应该看到你不能有浮动的caseif 语句。目前你有 if (sw[0] == 1'b0) 不包含在一个块中。

【讨论】:

    【解决方案2】:

    首先,Verilog 是硬件描述语言。它不是像 C 这样的编程语言。Verilog 实现更像是您在电路分析中学习的模拟电路,而不是编程语言。

    我认为你不能在没有 always 块的情况下使用 case 语句。此外,您在模块 startMod 中的 case 语句是多余的,因为信号正在通过您将它们传递到的模块中的 case 语句进行过滤。

    您正在添加两个 2 位信号,但您的开关是 4 位的!而且我更喜欢将 switch 作为电线而不是 reg。

    你的 KEY、LEDG、LEDR、CLOCK 在做什么?

    至于您最初的问题,您以正确的方式将信号传递给 dispBinHex 模块!只做一次,不要那么多次。模块是数字电路实现的块,不是 C/C++ 函数。当您实例化一个模块时,就像将电线连接到该电路块。它们只是连接。因此,您的 hex0 应该是一个简单的输出,而不是输出 reg。

    【讨论】:

    • 我按照您的建议对代码进行了更正,但仍然出现错误。我将它们包含在帖子的编辑版本中。 hex0 也必须是一个 reg,否则我们的教授认为这太容易了。
    猜你喜欢
    • 2020-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多