1

Verilog で初歩的なシングル サイクル CPU を構築することが私たちの任務ですが、それ以上の基本的なモジュールを正しく理解できていません。たとえば、Instruction Memory モジュールをテストするために、16 進数の命令を含むテキスト ファイル "hw3Test.txt" が提供されているので、それを IM に丸呑みしようとしています。

00221820
AC010000
8C240000
10210001
00001820
00411822

テストベンチを実行すると、メモリに入る命令は 2 行目、3 行目、4 行目だけであることがわかります。IMモジュールは次のとおりです。

module IM(addr, clk, inst);

   input [31:0] addr;
   input clk;
   output reg [31:0] inst;


   reg [31:0] mem [255:0];
   initial begin
          $readmemh("hw3Test.txt", mem);
   end
   always @( posedge clk) begin
          inst=mem[addr[31:2]];
   end
endmodule

そしてテストベンチ:

module imtest;
    // Inputs
    reg [31:0] addr;
    reg clk;
    // Outputs
    wire [31:0] inst;
    // Instantiate the Unit Under Test (UUT)
    IM uut (
        .addr(addr), 
        .clk(clk), 
        .inst(inst)
    );
    initial begin
        // Initialize Inputs
        addr = 0;
        clk = 0;
        // Wait 100 ns for global reset to finish
        #100;
        // Add stimulus here
        clk = 0;
        addr = 0;
        #100;
        forever begin
            #20;
            clk = ~clk;
            addr = addr + 4;
        end 
    end      
endmodule

初期化された値を除いて、rst 信号と clk 信号以外のすべてが有効な値を示さないため、PC-to-IM モジュールを正しく取得できているかどうかもわかりません。誰かが私が間違っているところを指摘できますか?

module pc_im(
    // Inputs
    rst, clk, PCin,

    // Outputs
    inst, PCout
    );

    input clk, rst;
    input [31:0] PCin;
    output reg [31:0] inst;
    output reg [31:0] PCout;

    PC mypc (
        .clk(clk),
        .rst(rst),
        .PCin(PCin),
        .PCout(PCout)
    );

    IM myim(
        .clk(clk),
        .addr(PCout),
        .inst(inst)
    );

endmodule

PC.v モジュールは次のとおりです。

module PC(rst, clk, PCin, PCout);
    input clk, rst;
    input [31:0] PCin;
    output reg [31:0] PCout;

    always @(posedge clk) begin
        if (rst) PCout <= 0;
        else PCout <= PCin + 4;
    end

endmodule

最後に、テストベンチ:

module pcimtest;

    // Inputs
    reg rst;
    reg clk;
    reg [31:0] PCin;

    // Outputs
    wire [31:0] inst;
    wire [31:0] PCout;

    // Instantiate the Unit Under Test (UUT)
    pc_im uut (
        .rst(rst), 
        .clk(clk), 
        .PCin(PCin), 
        // Outputs
        .inst(inst), 
        .PCout(PCout)
    );

    initial begin
        // Initialize Inputs
        rst = 1;
        clk = 0;
        PCin = 0;

        // Wait 100 ns for global reset to finish
        #100;
        rst = 0;

        forever begin
            #100;
            clk <= ~clk;
            PCin <= PCout;
        end

        // Add stimulus here

    end

endmodule
4

1 に答える 1

2

疑わしいと思われる点をいくつか示します。

問題1

通常は、レジスターを推論するためのブロックでノンブロッキング代入を使用することをお勧めします。

すなわち変更

always @( posedge clk) begin
      inst=mem[addr[31:2]];
end

always @( posedge clk) begin
      inst<=mem[addr[31:2]];
end

問題 2

信号を 1 クロック サイクルあたり 2 回、ネガティブ エッジで 1 回、ポジティブ エッジで 1 回変更しています。

変化する:

    forever begin
        #20;
        clk = ~clk;
        addr = addr + 4;
    end 

    forever begin
        #20;
        clk = 1;
        #20;
        clk = 0;
        addr = addr + 4;
    end

問題 3

同期リセットを使用していますが、リセット中にクロックを供給していません。

コードを検討する

always @(posedge clk) begin
    if (rst) PCout <= 0;
    else PCout <= PCin + 4;
end

このブロックは正のクロック エッジでのみアクティブになります。ただし、クロックが一時停止している間にリセットをハイにすると、リセットは発生しません。

変化する

    rst = 1;
    clk = 0;
    PCin = 0;

    // Wait 100 ns for global reset to finish
    #100;

    rst = 1;
    clk = 0;
    PCin = 0;
    #20
    clk = 1;
    #20
    clk = 0;

    // Wait 100 ns for global reset to finish
    #100;
于 2013-06-02T19:14:01.243 に答える