皋陶 发表于 2021-3-5 21:43:42

E203 itcm

本帖最后由 皋陶 于 2021-3-5 21:43 编辑

E203 itcm是64Kb,所以地址总线为16位,2^16=64Kb, 数据线宽度为64 bits(8 bytes),所以address width是16-3=13bit,ram depth 是2^16/8=2^13。
      itcm的基地址默认是0x8000_0000。
      在目录e200_opensource/riscv-tools/riscv-tests/isa/generated,这儿有很多生成好的test文件。比如test rv32ui-p-andi
      文件rv32ui-p-andi是riscv的可执行elf文件, rv32ui-p-andi.dump是对应的汇编文件,rv32ui-p-andi.verilog是对于的机器码文件,可以在verilog中用下面的代码把要执行的机器码装入itcm中。
//default itcm size is 64Kb, so E203_ITCM_RAM_DP=13
    reg itcm_mem ;
    initial begin
      $readmemh({testcase, ".verilog"}, itcm_mem);

      for (i=0;i<(`E203_ITCM_RAM_DP);i=i+1) begin
          `ITCM.mem_r = itcm_mem;
          `ITCM.mem_r = itcm_mem;
          `ITCM.mem_r = itcm_mem;
          `ITCM.mem_r = itcm_mem;
          `ITCM.mem_r = itcm_mem;
          `ITCM.mem_r = itcm_mem;
          `ITCM.mem_r = itcm_mem;
          `ITCM.mem_r = itcm_mem;
      end
itcm实际上就是一块sram,对itcm的读写如下,读写数据宽度都是按32bit进行的,对于写可以通过write mask只写某个byte。
module sirv_sim_ram
#(parameter DP = 512,
parameter FORCE_X2ZERO = 0,
parameter DW = 32,
parameter MW = 4,
parameter AW = 32
)
(
input             clk,
input din,//input data
input addr,//input address
input             cs, //chip select
input             we, //write enable
input   wem,//write enable mask
output    dout //write data out
);

    reg mem_r ;
    reg addr_r;
    wire wen;
    wire ren;

    assign ren = cs & (~we);
    //it is 4 bits, and every bit mask a byte write
    assign wen = ({MW{cs & we}} & wem);



    genvar i;

    always @(posedge clk)
    begin
      if (ren) begin
            addr_r <= addr;
      end
    end

    generate
      for (i = 0; i < MW; i = i+1) begin :mem
      if((8*i+8) > DW ) begin: last
          always @(posedge clk) begin
            if (wen) begin
               mem_r <= din;
            end
          end
      end
      else begin: non_last
          always @(posedge clk) begin
            if (wen) begin
               mem_r <= din;
            end
          end
      end
      end
    endgenerate

wire dout_pre;
assign dout_pre = mem_r;

generate
   if(FORCE_X2ZERO == 1) begin: force_x_to_zero
      for (i = 0; i < DW; i = i+1) begin:force_x_gen
          `ifndef SYNTHESIS//{
         assign dout = (dout_pre === 1'bx) ? 1'b0 : dout_pre;
          `else//}{
         assign dout = dout_pre;
          `endif//}
      end
   end
   else begin:no_force_x_to_zero
   assign dout = dout_pre;
   end
endgenerate


endmodule
testbench文件module sirv_sim_ram_tb;
reg clk=0;
reg cs=1;
reg we=1;
reg wem=4'b1111;
reg addr;
reg din;

wire dout;
integer i,j;


sirv_sim_ram #(
    .FORCE_X2ZERO (1),
    .DP (64),
    .AW (6),
    .MW (4),
    .DW (32)
)u_sirv_sim_ram (
    .clk   (clk),
    .din   (din),
    .addr(addr),
    .cs    (cs),
    .we    (we),
    .wem   (wem),
    .dout(dout)
);
always #10 clk = ~clk;

initial
begin
for(i=0; i<16; i=i+1)
      #20 addr=i;
#20
#20 we = 0;
addr = 0;
#20 addr = 1;
#20 addr = 2;
#20 addr = 3;
#20 addr = 4;
#20 addr = 5;
#20 addr = 6;

end

initial
begin
for(j=0; j<16; j=j+1)
      #20 din=j;
end
initial
begin
      //$dumpfile("dump.vcd");
      //$dumpvars;
      $fsdbDumpfile("dump.fsdb");
      $fsdbDumpvars("+all");
end


initial
begin
    $monitor($time,,,"%d,%d,%d,%d,%d,%d)",cs,din,addr,we,wem,dout);
   #1000 $finish;
end
endmodule
页: [1]
查看完整版本: E203 itcm