SystemVrilogでレジスタファイルを記述してみる
SystemVerilogで2種類のレジスタファイル(アドレス長:2ビット、レジスタ数:4、データ長:32ビット)を記述してみる。
レジスタファイル(レジスタとMUXで構成)
個人的にはこちらの記述の方が読みやすいかなぁ。
(レジスタ数が増えると、コードの行数が長くなるけど。。。)
/* regfile.v */ module regfile #(parameter A_WIDTH = 2, D_WIDTH = 32) (input clk, input [A_WIDTH-1:0] readaddr1, input [A_WIDTH-1:0] readaddr2, input [A_WIDTH-1:0] writeaddr, input we, input [D_WIDTH-1:0] writedata, output [D_WIDTH-1:0] readdata1, output [D_WIDTH-1:0] readdata2); logic [D_WIDTH-1:0] r0 = 0; logic [D_WIDTH-1:0] r1 = 0; logic [D_WIDTH-1:0] r2 = 0; logic [D_WIDTH-1:0] r3 = 0; /* Reading Register 1 */ assign readdata1 = (readaddr1 == 0) ? r0 : (readaddr1 == 1) ? r1 : (readaddr1 == 2) ? r2 : r3; /* Reading Register 2 */ assign readdata2 = (readaddr2 == 0) ? r0 : (readaddr2 == 1) ? r1 : (readaddr2 == 2) ? r2 : r3; /* Writing data */ always_ff @(posedge clk) begin if(we) begin case(writeaddr) 0: r0 <= writedata; 1: r1 <= writedata; 2: r2 <= writedata; 3: r3 <= writedata; default : r0 <= 32'd0; endcase end end endmodule
レジスタファイル(RAMで構成)
こちらの記述は↑の記述よりコード数が少ない。
/* regfile_ram.sv */ module regfile_ram #(parameter A_WIDTH = 2, D_WIDTH=32) (input clk, input [A_WIDTH-1:0] readaddr1, readaddr2, input [A_WIDTH-1:0] writeaddr, input we, input [D_WIDTH-1:0] writedata, output [D_WIDTH-1:0] readdata1, output [D_WIDTH-1:0] readdata2); logic [D_WIDTH-1:0] dmem [0:2**A_WIDTH-1] ; always_ff @(posedge clk) begin if(we) dmem[writeaddr] <= writedata; end assign readdata1 = dmem[readaddr1]; assign readdata2 = dmem[readaddr2]; endmodule