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]