有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 皋陶 于 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 [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
复制代码
完 |