如何在 always 块中与其他语句同时执行任务?

How to execute task concurrently with other statements in an always block?

我正在用 Verilog 为 8*4 RAM 编写代码。对于内存的每个二进制单元,我使用一个 SR 触发器。最初,每个单元格都分配有 1'bx。逻辑似乎是正确的,但输出却不正确。这可能是因为语句没有同时执行。谁能建议我如何让任务 SRFlipFlop 与其他语句同时执行?

module memory(addr, read_data, rw, write_data, clk);
// read_data is the data read
// rw specifies read or write operation. 1 for read and 0 for write
// write data is the data to be written
// addr is the address to be written or read    

task SRFlipFlop;
input d,r,s,clk; // d is the value initially stored
output q;  
begin
case({s,r})
{1'b0,1'b0}: q<=d;
{1'b0,1'b1}: q<=1'b0;
{1'b1,1'b0}: q<=1'b1;
{1'b1,1'b1}: q<=1'bx;
endcase
end
endtask

task decoder;     // a 3 to 8 line decoder
input [2:0] A;
input E;
output [7:0] D;
if (!E)
    D <= 16'b0000000000000000;
else
    begin
        case (A)
            3'b000 : D <= 8'b00000001;
            3'b001 : D <= 8'b00000010;
            3'b010 : D <= 8'b00000100;
            3'b011 : D <= 8'b00001000;
            3'b100 : D <= 8'b00010000;
            3'b101 : D <= 8'b00100000;
            3'b110 : D <= 8'b01000000;
            3'b111 : D <= 8'b10000000;
        endcase
    end
endtask


output reg [3:0] read_data;
input [3:0] write_data;
input [2:0] addr;
input rw, clk;
reg [3:0] memory [7:0];
reg [3:0] r [7:0];
reg [3:0] s [7:0];
reg [3:0] intermediate;
reg [3:0] select [7:0];
reg [7:0] out;
reg [7:0] out1;
integer i,j,k,l;
initial 
  begin
    for (i = 0; i <= 7; i=i+1) 
        begin
            for (j = 0; j <= 3; j=j+1) 
                begin
                 memory[i][j] = 1'bx;
                 r[i][j] = 1'b0;
                 s[i][j] = 1'b0;
                 select[i][j] = 1'b0;
                end
        end
  end
  always @(posedge clk)
  begin
    decoder(addr, 1'b1, out);
     for (i = 0; i <= 7; i=i+1)
        begin
            if (out[i] == 1'b1)
                begin
                for (j = 0; j <= 3; j=j+1)
                    begin
                        select[i][j] <= 1'b1;
                        s[i][j] <= write_data[j] & !rw & select[i][j];
                        r[i][j] <= !write_data[j] & !rw & select[i][j];
                        SRFlipFlop(memory[i][j],r[i][j],s[i][j],clk,intermediate);
                        memory[i][j] <= intermediate;
                        read_data[j] <= memory[i][j];
                    end
                end
        end
  end
endmodule

您的代码风格非常面向软件。就我个人而言,我想知道我的代码看起来像一个电路,所以我不会使用嵌套的 for 循环和任务,而是使用模块和生成循环来创建我的电路。

我没能使你的代码工作,但我怀疑错误是因为 s 和 r 在每次迭代中都没有重置为零。

我在这里创建了一个功能设计: http://www.edaplayground.com/x/Guc

我没有使用初始块来初始化值,而是添加了异步重置。

SRFF 任务已转换为模块。一个 RAMblock 模块实例化四个 SRFF 模块。在内存模块中实例化了 8 个 RAMblocks。

我已将您的压缩数组(reg [] a [])转换为未压缩数组(reg [][] a),以便能够在没有 for 循环的情况下对多个位执行按位运算。

如果您对代码有任何疑问,请随时给我发消息。

编辑:也许在此设计中要注意的最重要的事情是我将时序电路与组合电路分开。这样,控制在 clk 的 posedge 上应该更新什么以及什么应该只是对在 posedge 上执行的更改的组合反应要容易得多。