Simulation 零件选择通过导线时在模拟器中的行为异常

Simulation 零件选择通过导线时在模拟器中的行为异常,simulation,verilog,Simulation,Verilog,我有一个Verilog模块,它从32位总线上读取数据,一次读取一个字,然后将这些字组合成一个更宽的寄存器,作为其他几个模块的输入。输入总线是一个内存总线,所以每个字都有一个地址,标识我必须存储它的位置 我使用part select将单词存储到注册表中。因为总线上最低地址的字对应于reg中最重要的字,所以我通过翻转地址的位,然后附加三个0位,将其从字节偏移量转换为位偏移量,来生成部分选择的偏移量 这实际上效果很好。但因为我使用翻转位,然后在几个位置添加三个零逻辑,所以我决定将其指定给导线,然后在零

我有一个Verilog模块,它从32位总线上读取数据,一次读取一个字,然后将这些字组合成一个更宽的寄存器,作为其他几个模块的输入。输入总线是一个内存总线,所以每个字都有一个地址,标识我必须存储它的位置

我使用part select将单词存储到注册表中。因为总线上最低地址的字对应于reg中最重要的字,所以我通过翻转地址的位,然后附加三个0位,将其从字节偏移量转换为位偏移量,来生成部分选择的偏移量

这实际上效果很好。但因为我使用翻转位,然后在几个位置添加三个零逻辑,所以我决定将其指定给导线,然后在零件选择中使用导线作为偏移量。然而,当我这样做的时候,突然它根本不起作用。第一次写入word 0是有效的。但在第二个循环中,写入字1会覆盖字0!然后,以下对word 2的写入将保存在word 1中。这就好像导线是一个reg,计算偏移量的结果直到下一个周期才被看到。这似乎很奇怪,因为我认为电线只是地址总线的线路,通过一些非门;每当地址改变时,偏移量就改变

我把这个问题归结为以下两个例子。我使用3位地址总线和8位值只是为了更容易地看到发生了什么。有人能解释为什么他们表现出不同的行为吗?我认为这是由于Verilog调度阻塞的方式的某些特殊性造成的,但我无法解释。显然,我可以只使用工作版本,或者使用数组而不是宽注册表,但我认为理解这一点的原因将在将来帮助我

谢谢大家!

作品:

module busif(
        input clock,
        input [2:0] address,
        input read,
        input write,
        input [7:0] data_in,
        output reg [7:0] data_out
    );

    // 8 bytes of memory (3-bit address).
    reg [63:0] memory;

    always @(posedge clock) begin
        if (write) begin
            memory[{~address, 3'b000} +: 8] <= data_in;
        end
        // (read case omitted)
    end       

endmodule
不工作偏移似乎需要1个周期才能通过导线传播:

module busif(
        input clock,
        input [2:0] address,
        input read,
        input write,
        input [7:0] data_in,
        output reg [7:0] data_out
    );

    // 8 bytes of memory (3-bit address).
    reg [63:0] memory;

    wire [5:0] offset;
    assign offset = {~address, 3'b000};

    always @(posedge clock) begin
        if (write) begin
            memory[offset +: 8] <= data_in;
        end
        // (read case omitted)
    end       

endmodule

您的代码没有任何问题-请注意,isim在历史上一直都是非常有缺陷的,而且可能现在仍然是。几年前我就放弃了

简单测试台连接-对于您的两个模块,Modelsim和Icarus都可以通过

/**
 * Maia testbench: download and install maia from maia-eda.net. To run the
 * testbench, save this code as tb.tv, and:
 *
 * rtv tb.tv busif.v
 *
 * On success, you should get the following output:
 *
 * # finished: 'memory' is 102040810204080
 * # (Log) (80 ns) 8 vectors executed (8 passes, 0 fails)
 *
 */
#pragma _StrictChecking 0  // turn off some type checking for simplicity

DUT {
   module busif
      (input           clock,
      input [2:0]      address,
      input            read,
      input            write,
      input [7:0]      data_in,
      output reg [7:0] data_out);

   signal(output reg[63:0] memory);                // internal signals to test

   [clock, write, address, data_in] -> [memory];   // vector definition
   create_clock clock;                             // define a clock
}

main() {
   int   i;
   var64 expected = 64`hxxxxxxxx_xxxxxxxx;
   var64 mask     = 64`hff000000_00000000;
   var64 data;

   for(i=0; i<8; i++) {
      data = 64`h1 << ((7-i)*8) + i;
      expected &= ~mask;                           // clear out the new byte
      expected |= data;                            // get the expected result
      mask >>= 8;

      [.C, 1, i, 1<<i] -> [expected];              // clock and test
   }
   report("finished: 'memory' is %x\n", memory);   // read this backwards!
}

您使用的是什么模拟器?上传显示有相关信号的波形图像可能会有所帮助。