zoukankan      html  css  js  c++  java
  • E203 itcm

          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 [7:0] itcm_mem [0:(`E203_ITCM_RAM_DP*8)-1];
        initial begin
          $readmemh({testcase, ".verilog"}, itcm_mem);
    
          for (i=0;i<(`E203_ITCM_RAM_DP);i=i+1) begin
              `ITCM.mem_r[i][00+7:00] = itcm_mem[i*8+0];
              `ITCM.mem_r[i][08+7:08] = itcm_mem[i*8+1];
              `ITCM.mem_r[i][16+7:16] = itcm_mem[i*8+2];
              `ITCM.mem_r[i][24+7:24] = itcm_mem[i*8+3];
              `ITCM.mem_r[i][32+7:32] = itcm_mem[i*8+4];
              `ITCM.mem_r[i][40+7:40] = itcm_mem[i*8+5];
              `ITCM.mem_r[i][48+7:48] = itcm_mem[i*8+6];
              `ITCM.mem_r[i][56+7:56] = itcm_mem[i*8+7];
          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  [DW-1  :0] din,//input data 
      input  [AW-1  :0] addr,//input address
      input             cs, //chip select
      input             we, //write enable
      input  [MW-1:0]   wem,//write enable mask
      output [DW-1:0]   dout //write data out
    );
    
        reg [DW-1:0] mem_r [0:DP-1];
        reg [AW-1:0] addr_r;
        wire [MW-1:0] 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[i]) begin
                   mem_r[addr][DW-1:8*i] <= din[DW-1:8*i];
                end
              end
            end
            else begin: non_last
              always @(posedge clk) begin
                if (wen[i]) begin
                   mem_r[addr][8*i+7:8*i] <= din[8*i+7:8*i];
                end
              end
            end
          end
        endgenerate
    
      wire [DW-1:0] dout_pre;
      assign dout_pre = mem_r[addr_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[i] = (dout_pre[i] === 1'bx) ? 1'b0 : dout_pre[i];
              `else//}{
             assign dout[i] = dout_pre[i];
              `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[3:0] wem=4'b1111;
    reg[31:0] addr;
    reg[31:0] din;
    
    wire[31:0] 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
    



    image










  • 相关阅读:
    telnet退出
    Eclipse srever起来时,时间超过45s。
    maven报错 Failure to transfer org.apache.maven.plugins:maven-compiler-plugin:pom:3.5.0 from
    需求讨论
    PyTorch学习笔记之计算图
    PyTorch学习笔记之CBOW模型实践
    PyTorch学习笔记之n-gram模型实现
    PyTorch学习笔记之初识word_embedding
    7月3日-9日_周报
    python学习笔记之heapq内置模块
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/11446162.html
Copyright © 2011-2022 走看看