[Add] add icache dcache axi & pass test n46(before syscall)

This commit is contained in:
2023-07-20 17:19:04 +08:00
parent 60d8c35fef
commit 1b4c6eee10
17 changed files with 3577 additions and 335 deletions

428
lacpu/rtl/cpu/axi_ctrl.v Normal file
View File

@@ -0,0 +1,428 @@
`default_nettype wire
module axi_ctrl_v5
#(
parameter TAG_WD = 21,
parameter INDEX_WD = 64,
parameter CACHELINE_WD = 512,
parameter STAGE_WD = 12
)
(
input clk,
input reset,
// icache interface
input icache_re, // miss
input [31 :0] icache_raddr, // miss_addr
output reg [CACHELINE_WD -1:0] icache_cacheline_new,
input icache_we, // we_back
input [31 :0] icache_waddr, // waddr
input [CACHELINE_WD -1:0] icache_cacheline_old, // wback
output reg icache_refresh,
// dcache interface
input dcache_re, // miss
input [31 :0] dcache_raddr, // miss_addr
output reg [CACHELINE_WD -1:0] dcache_cacheline_new,
input dcache_we, // we_back
input [31 :0] dcache_waddr, // waddr
input [CACHELINE_WD -1:0] dcache_cacheline_old, // wback
output reg dcache_refresh, // fin
// uncache interface
input uncache_en,
input [3 :0] uncache_we,
input [31 :0] uncache_addr,
input [31 :0] uncache_wdata,
output reg [31 :0] uncache_rdata,
output reg uncache_refresh,
//总线侧接口
//读地址通道信号
output reg [3 :0] arid, //读地址ID用来标志一组写信号
output reg [31:0] araddr, //读地址给出一次写突发传输的读地址
output reg [3 :0] arlen, //突发长度给出突发传输的次数
output reg [2 :0] arsize, //突发大小给出每次突发传输的字节数
output reg [1 :0] arburst, //突发类型
output reg [1 :0] arlock, //总线锁信号可提供操作的原子性
output reg [3 :0] arcache, //内存类型表明一次传输是怎样通过系统的
output reg [2 :0] arprot, //保护类型表明一次传输的特权级及安全等级
output reg arvalid, //有效信号表明此通道的地址控制信号有效
input arready, //表明""可以接收地址和对应的控制信号
//读数据通道信号
input [3 :0] rid, //读ID tag
input [31:0] rdata, //读数据
input [1 :0] rresp, //读响应表明读传输的状态
input rlast, //表明读突发的最后一次传输
input rvalid, //表明此通道信号有效
output reg rready, //表明主机能够接收读数据和响应信息
//写地址通道信号
output reg [3 :0] awid, //写地址ID用来标志一组写信号
output reg [31:0] awaddr, //写地址给出一次写突发传输的写地址
output reg [3 :0] awlen, //突发长度给出突发传输的次数
output reg [2 :0] awsize, //突发大小给出每次突发传输的字节数
output reg [1 :0] awburst, //突发类型
output reg [1 :0] awlock, //总线锁信号可提供操作的原子性
output reg [3 :0] awcache, //内存类型表明一次传输是怎样通过系统的
output reg [2 :0] awprot, //保护类型表明一次传输的特权级及安全等级
output reg awvalid, //有效信号表明此通道的地址控制信号有效
input awready, //表明""可以接收地址和对应的控制信号
//写数据通道信号
output reg [3 :0] wid, //一次写传输的ID tag
output reg [31:0] wdata, //写数据
output reg [3 :0] wstrb, //写数据有效的字节线用来表明哪8bits数据是有效的
output reg wlast, //表明此次传输是最后一个突发传输
output reg wvalid, //写有效表明此次写有效
input wready, //表明从机可以接收写数据
//写响应通道信号
input [3 :0] bid, //写响应ID tag
input [1 :0] bresp, //写响应表明写传输的状态 00为正常当然可以不理会
input bvalid, //写响应有效
output reg bready //表明主机能够接收写响应
);
reg [CACHELINE_WD -1:0] icache_rdata_buffer;
reg [CACHELINE_WD -1:0] icache_wdata_buffer;
reg [CACHELINE_WD -1:0] dcache_rdata_buffer;
reg [CACHELINE_WD -1:0] dcache_wdata_buffer;
reg [31 :0] icache_raddr_buffer;
reg [31 :0] icache_waddr_buffer;
reg [31 :0] dcache_raddr_buffer;
reg [31 :0] dcache_waddr_buffer;
reg [3 :0] icache_offset;
reg [3 :0] dcache_offset;
reg [3 :0] dcache_offset_w;
reg icache_re_buffer;
reg dcache_re_buffer;
reg icache_we_buffer;
reg dcache_we_buffer;
reg uncache_en_buffer;
reg [3 :0] uncache_we_buffer;
reg [31 :0] uncache_addr_buffer;
reg [31 :0] uncache_wdata_buffer;
reg [31 :0] uncache_rdata_buffer;
reg [STAGE_WD -1:0] stage;
reg [STAGE_WD -1:0] stage_w;
always @(posedge clk) begin
if(reset) begin
arid <= 4'b0000;
araddr <= 32'b0;
arlen <= 4'b0000;
arsize <= 3'b010;
arburst <= 2'b01;
arlock <= 2'b00;
arcache <= 4'b0000;
arprot <= 3'b000;
arvalid <= 1'b0;
rready <= 1'b0;
stage <= {{(STAGE_WD-1){1'b0}}, 1'b1};
icache_refresh <= 0;
dcache_refresh <= 0;
icache_cacheline_new <= 0;
dcache_cacheline_new <= 0;
uncache_refresh <= 1'b0;
uncache_rdata <= 32'b0;
end
else begin
case (1'b1)
stage[0]: begin
icache_refresh <= 1'b0;
dcache_refresh <= 1'b0;
uncache_refresh <= 1'b0;
icache_re_buffer <= icache_re;
icache_raddr_buffer <= icache_raddr;
icache_we_buffer <= icache_we;
icache_waddr_buffer <= icache_waddr;
dcache_re_buffer <= dcache_re;
dcache_raddr_buffer <= dcache_raddr;
dcache_we_buffer <= dcache_we;
dcache_waddr_buffer <= dcache_waddr;
uncache_en_buffer <= uncache_en;
uncache_we_buffer <= uncache_we;
uncache_addr_buffer <= uncache_addr;
uncache_wdata_buffer <= uncache_wdata;
if (dcache_we|(uncache_en&((|uncache_we)))) begin
stage <= stage << 1;
end
else if (icache_re|dcache_re|(uncache_en&~(|uncache_we))) begin
stage <= stage << 2;
end
end
stage[1]: begin
icache_wdata_buffer <= icache_cacheline_old;
dcache_wdata_buffer <= dcache_cacheline_old;
if (icache_re_buffer|dcache_re_buffer|(uncache_en_buffer&~(|uncache_we_buffer))) begin
stage <= stage << 1;
end
else begin
stage <= {1'b0,1'b1,10'b0};
end
end
stage[2]:begin
if (icache_re_buffer) begin
arid <= 4'b0;
araddr <= icache_raddr_buffer;
arlen <= 4'hf;
arsize <= 3'b010;
arvalid <= 1'b1;
stage <= stage << 1;
end
else begin
stage <= stage << 3;
end
end
stage[3]:begin
if (arready) begin
arvalid <= 1'b0;
araddr <= 32'b0;
rready <= 1'b1;
icache_offset <= 4'd0;
stage <= stage << 1;
end
end
stage[4]:begin
if (!rlast&rvalid) begin
icache_rdata_buffer[icache_offset*32+:32] <= rdata;
icache_offset <= icache_offset + 1'b1;
end
else if(rlast&rvalid) begin
icache_rdata_buffer[icache_offset*32+:32] <= rdata;
rready <= 1'b0;
stage <= stage << 1;
end
end
stage[5]:begin
if (dcache_re_buffer) begin
arid <= 4'b1;
araddr <= dcache_raddr_buffer;
arlen <= 4'hf;
arsize <= 3'b010;
arvalid <= 1'b1;
stage <= stage << 1;
end
else if (uncache_en_buffer&~(|uncache_we_buffer)) begin
arid <= 4'b1;
araddr <= uncache_addr_buffer;
arlen <= 4'b0;
arsize <= 3'b010;
arvalid <= 1'b1;
stage <= stage << 3;
end
else begin
stage <= {1'b0,1'b1,10'b0};
end
end
stage[6]:begin
if (arready) begin
arvalid <= 1'b0;
araddr <= 32'b0;
rready <= 1'b1;
dcache_offset <= 4'd0;
stage <= stage << 1;
end
end
stage[7]:begin
if (!rlast&rvalid) begin
dcache_rdata_buffer[dcache_offset*32+:32] <= rdata;
dcache_offset <= dcache_offset + 1'b1;
end
else if (rlast&rvalid) begin
dcache_rdata_buffer[dcache_offset*32+:32] <= rdata;
rready <= 1'b0;
stage <= {1'b0,1'b1,10'b0};
end
end
stage[8]:begin
if (arready) begin
arvalid <= 1'b0;
araddr <= 32'b0;
rready <= 1'b1;
stage <= stage << 1;
end
end
stage[9]:begin
if (rvalid) begin
uncache_rdata_buffer <= rdata;
rready <= 1'b0;
stage <= {1'b0,1'b1,10'b0};
end
end
stage[10]:begin
if (stage_w[10]|stage_w[0]) begin
stage <= stage << 1;
end
end
stage[11]:begin
if (icache_re_buffer) begin
icache_refresh <= 1'b1;
icache_cacheline_new <= icache_rdata_buffer;
end
if (dcache_re_buffer) begin
dcache_refresh <= 1'b1;
dcache_cacheline_new <= dcache_rdata_buffer;
end
if (uncache_en_buffer) begin
uncache_refresh <= 1'b1;
uncache_rdata <= uncache_rdata_buffer;
end
stage <= 0;
end
default:begin
stage <= {{(STAGE_WD-1){1'b0}}, 1'b1};
icache_refresh <= 1'b0;
dcache_refresh <= 1'b0;
uncache_refresh <= 1'b0;
end
endcase
end
end
always @ (posedge clk) begin
if (reset) begin
awid <= 4'b0001;
awaddr <= 32'b0;
awlen <= 4'b0000;
awsize <= 3'b010;
awburst <= 2'b01;
awlock <= 2'b00;
awcache <= 4'b0000;
awprot <= 3'b000;
awvalid <= 1'b0;
wid <= 4'b0001;
wdata <= 32'b0;
wstrb <= 4'b0000;
wlast <= 1'b0;
wvalid <= 1'b0;
bready <= 1'b0;
stage_w <= {{(STAGE_WD-1){1'b0}}, 1'b1};
end
else begin
case (1'b1)
stage_w[0]:begin
if (stage[1]) begin
if (dcache_we_buffer) begin
awid <= 4'b1;
awaddr <= dcache_waddr_buffer;
awlen <= 4'hf;
awsize <= 3'b010;
awvalid <= 1'b1;
wstrb <= 4'b1111;
wlast <= 1'b0;
bready <= 1'b1;
dcache_offset_w <= 4'b0;
stage_w <= stage_w << 1;
end
else if (|uncache_we_buffer) begin // write
awid <= 4'b1;
awaddr <= uncache_addr_buffer;
awlen <= 4'b0;
case (uncache_we_buffer)
4'b0001,4'b0010,4'b0100,4'b1000:begin
awsize <= 3'b000;
wstrb <= uncache_we_buffer;
end
4'b0011,4'b1100:begin
awsize <= 3'b001;
wstrb <= uncache_we_buffer;
end
4'b1111:begin
awsize <= 3'b010;
wstrb <= uncache_we_buffer;
end
default:begin
awsize <= 3'b010;
wstrb <= uncache_we_buffer;
end
endcase
awvalid <= 1'b1;
wlast <= 1'b0;
bready <= 1'b1;
stage_w <= stage_w << 4;
end
end
end
stage_w[1]:begin
if (awready) begin
awvalid <= 1'b0;
awaddr <= 32'b0;
wdata <= dcache_wdata_buffer[dcache_offset_w*32+:32];
wvalid <= 1'b1;
wlast <= dcache_offset_w == 4'b1111 ? 1'b1 : 1'b0;
dcache_offset_w <= dcache_offset_w + 1'b1;
if (dcache_offset_w == 4'b1111) begin
stage_w <= stage_w << 1;
end
end
end
stage_w[2]:begin
if (wready) begin
wdata <= 32'b0;
wvalid <= 1'b0;
wlast <= 1'b0;
stage_w <= stage_w << 1;
end
end
stage_w[3]:begin
if (bvalid) begin
bready <= 1'b0;
stage_w <= {1'b0,1'b1,{10{1'b0}}};
end
end
stage_w[4]:begin
if (awready) begin
awvalid <= 1'b0;
awaddr <= 32'b0;
wdata <= uncache_wdata_buffer;
wvalid <= 1'b1;
wlast <= 1'b1;
stage_w <= stage_w << 1;
end
end
stage_w[5]:begin
if (wready) begin
wdata <= 32'b0;
wvalid <= 1'b0;
wlast <= 1'b0;
stage_w <= stage_w << 1;
end
end
stage_w[6]:begin
if (bvalid) begin
bready <= 1'b0;
stage_w <= {1'b0,1'b1,{10{1'b0}}};
end
end
stage_w[10]:begin
if (stage[11]) begin
stage_w <= {{(STAGE_WD-1){1'b0}}, 1'b1};
end
end
default:begin
stage_w <= {{(STAGE_WD-1){1'b0}}, 1'b1};
end
endcase
end
end
endmodule

792
lacpu/rtl/cpu/cache_data.v Normal file
View File

@@ -0,0 +1,792 @@
`default_nettype wire
module cache_data_v5
#(
parameter CACHELINE_WD = 512,
parameter TAG_WD = 21,
parameter HIT_WD = 2
)
(
input clk,
input reset,
input write_back,
input [ 1:0] hit,
input lru,
input cached,
// sram_port
input sram_en,
input [ 3:0] sram_we,
input [31:0] sram_addr,
input [31:0] sram_wdata,
output [31:0] sram_rdata,
input refresh,
input [CACHELINE_WD -1:0] cacheline_new,
output [CACHELINE_WD -1:0] cacheline_old
);
wire [31 :0] rdata_way0 [15:0];
wire [31 :0] rdata_way1 [15:0];
wire [TAG_WD -2:0] tag;
wire [5 :0] index;
wire [5 :0] offset;
reg [HIT_WD -1:0] hit_r;
reg lru_r;
reg cached_r;
assign {tag,
index,
offset
} = sram_addr;
wire [15:0] bank_sel;
reg [15:0] bank_sel_r;
decoder_4_16 u_decoder_4_16(
.in (offset[5:2] ),
.out (bank_sel )
);
always @ (posedge clk) begin
if (reset) begin
hit_r <= 2'b0;
lru_r <= 1'b0;
cached_r <= 1'b1;
bank_sel_r <= 16'b0;
end
else begin
hit_r <= hit;
lru_r <= lru;
cached_r <= cached;
bank_sel_r <= bank_sel;
end
end
// data_bram_way0 begin
data_bram_bank bank0_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[0]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[31:0]:sram_wdata ), // 32
.douta (rdata_way0[0] ) // 32
);
data_bram_bank bank1_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[1]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[63:32]:sram_wdata ), // 32
.douta (rdata_way0[1] ) // 32
);
data_bram_bank bank2_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[2]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[95:64]:sram_wdata ), // 32
.douta (rdata_way0[2] ) // 32
);
data_bram_bank bank3_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[3]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[127:96]:sram_wdata ), // 32
.douta (rdata_way0[3] ) // 32
);
data_bram_bank bank4_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[4]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[159:128]:sram_wdata ), // 32
.douta (rdata_way0[4] ) // 32
);
data_bram_bank bank5_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[5]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[191:160]:sram_wdata ), // 32
.douta (rdata_way0[5] ) // 32
);
data_bram_bank bank6_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[6]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[223:192]:sram_wdata ), // 32
.douta (rdata_way0[6] ) // 32
);
data_bram_bank bank7_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[7]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[255:224]:sram_wdata ), // 32
.douta (rdata_way0[7] ) // 32
);
data_bram_bank bank8_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[8]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[287:256]:sram_wdata ), // 32
.douta (rdata_way0[8] ) // 32
);
data_bram_bank bank9_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[9]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[319:288]:sram_wdata ), // 32
.douta (rdata_way0[9] ) // 32
);
data_bram_bank bank10_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[10]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[351:320]:sram_wdata ), // 32
.douta (rdata_way0[10] ) // 32
);
data_bram_bank bank11_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[11]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[383:352]:sram_wdata ), // 32
.douta (rdata_way0[11] ) // 32
);
data_bram_bank bank12_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[12]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[415:384]:sram_wdata ), // 32
.douta (rdata_way0[12] ) // 32
);
data_bram_bank bank13_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[13]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[447:416]:sram_wdata ), // 32
.douta (rdata_way0[13] ) // 32
);
data_bram_bank bank14_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[14]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[479:448]:sram_wdata ), // 32
.douta (rdata_way0[14] ) // 32
);
data_bram_bank bank15_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[15]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[511:480]:sram_wdata ), // 32
.douta (rdata_way0[15] ) // 32
);
// data_bram_way0 end
// data_bram_way1 begin
data_bram_bank bank0_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[0]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[31:0]:sram_wdata ), // 32
.douta (rdata_way1[0] ) // 32
);
data_bram_bank bank1_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[1]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[63:32]:sram_wdata ), // 32
.douta (rdata_way1[1] ) // 32
);
data_bram_bank bank2_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[2]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[95:64]:sram_wdata ), // 32
.douta (rdata_way1[2] ) // 32
);
data_bram_bank bank3_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[3]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[127:96]:sram_wdata ), // 32
.douta (rdata_way1[3] ) // 32
);
data_bram_bank bank4_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[4]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[159:128]:sram_wdata ), // 32
.douta (rdata_way1[4] ) // 32
);
data_bram_bank bank5_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[5]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[191:160]:sram_wdata ), // 32
.douta (rdata_way1[5] ) // 32
);
data_bram_bank bank6_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[6]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[223:192]:sram_wdata ), // 32
.douta (rdata_way1[6] ) // 32
);
data_bram_bank bank7_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[7]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[255:224]:sram_wdata ), // 32
.douta (rdata_way1[7] ) // 32
);
data_bram_bank bank8_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[8]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[287:256]:sram_wdata ), // 32
.douta (rdata_way1[8] ) // 32
);
data_bram_bank bank9_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[9]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[319:288]:sram_wdata ), // 32
.douta (rdata_way1[9] ) // 32
);
data_bram_bank bank10_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[10]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[351:320]:sram_wdata ), // 32
.douta (rdata_way1[10] ) // 32
);
data_bram_bank bank11_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[11]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[383:352]:sram_wdata ), // 32
.douta (rdata_way1[11] ) // 32
);
data_bram_bank bank12_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[12]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[415:384]:sram_wdata ), // 32
.douta (rdata_way1[12] ) // 32
);
data_bram_bank bank13_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[13]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[447:416]:sram_wdata ), // 32
.douta (rdata_way1[13] ) // 32
);
data_bram_bank bank14_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[14]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[479:448]:sram_wdata ), // 32
.douta (rdata_way1[14] ) // 32
);
data_bram_bank bank15_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[15]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[511:480]:sram_wdata ), // 32
.douta (rdata_way1[15] ) // 32
);
// data_bram_way1 end
wire [31:0] sram_rdata_way0,sram_rdata_way1;
assign sram_rdata_way0 = ~cached_r ? 32'b0 :
bank_sel_r[ 0] ? rdata_way0[ 0] :
bank_sel_r[ 1] ? rdata_way0[ 1] :
bank_sel_r[ 2] ? rdata_way0[ 2] :
bank_sel_r[ 3] ? rdata_way0[ 3] :
bank_sel_r[ 4] ? rdata_way0[ 4] :
bank_sel_r[ 5] ? rdata_way0[ 5] :
bank_sel_r[ 6] ? rdata_way0[ 6] :
bank_sel_r[ 7] ? rdata_way0[ 7] :
bank_sel_r[ 8] ? rdata_way0[ 8] :
bank_sel_r[ 9] ? rdata_way0[ 9] :
bank_sel_r[10] ? rdata_way0[10] :
bank_sel_r[11] ? rdata_way0[11] :
bank_sel_r[12] ? rdata_way0[12] :
bank_sel_r[13] ? rdata_way0[13] :
bank_sel_r[14] ? rdata_way0[14] :
bank_sel_r[15] ? rdata_way0[15] : 32'b0;
assign sram_rdata_way1 = ~cached_r ? 32'b0 :
bank_sel_r[ 0] ? rdata_way1[ 0] :
bank_sel_r[ 1] ? rdata_way1[ 1] :
bank_sel_r[ 2] ? rdata_way1[ 2] :
bank_sel_r[ 3] ? rdata_way1[ 3] :
bank_sel_r[ 4] ? rdata_way1[ 4] :
bank_sel_r[ 5] ? rdata_way1[ 5] :
bank_sel_r[ 6] ? rdata_way1[ 6] :
bank_sel_r[ 7] ? rdata_way1[ 7] :
bank_sel_r[ 8] ? rdata_way1[ 8] :
bank_sel_r[ 9] ? rdata_way1[ 9] :
bank_sel_r[10] ? rdata_way1[10] :
bank_sel_r[11] ? rdata_way1[11] :
bank_sel_r[12] ? rdata_way1[12] :
bank_sel_r[13] ? rdata_way1[13] :
bank_sel_r[14] ? rdata_way1[14] :
bank_sel_r[15] ? rdata_way1[15] : 32'b0;
assign sram_rdata = hit_r[0] ? sram_rdata_way0 :
hit_r[1] ? sram_rdata_way1 : 32'b0;
wire [CACHELINE_WD-1:0] cacheline_old_way0, cacheline_old_way1;
assign cacheline_old_way0 = {rdata_way0[15],
rdata_way0[14],
rdata_way0[13],
rdata_way0[12],
rdata_way0[11],
rdata_way0[10],
rdata_way0[ 9],
rdata_way0[ 8],
rdata_way0[ 7],
rdata_way0[ 6],
rdata_way0[ 5],
rdata_way0[ 4],
rdata_way0[ 3],
rdata_way0[ 2],
rdata_way0[ 1],
rdata_way0[ 0]
};
assign cacheline_old_way1 = {rdata_way1[15],
rdata_way1[14],
rdata_way1[13],
rdata_way1[12],
rdata_way1[11],
rdata_way1[10],
rdata_way1[ 9],
rdata_way1[ 8],
rdata_way1[ 7],
rdata_way1[ 6],
rdata_way1[ 5],
rdata_way1[ 4],
rdata_way1[ 3],
rdata_way1[ 2],
rdata_way1[ 1],
rdata_way1[ 0]
};
assign cacheline_old = lru_r ? cacheline_old_way1 : cacheline_old_way0;
endmodule
module cache_data_v6
#(
parameter CACHELINE_WD = 512,
parameter TAG_WD = 21,
parameter HIT_WD = 2
)
(
input clk,
input reset,
input write_back,
input [ 1:0] hit,
input lru,
input cached,
// sram_port
input sram_en,
input [ 3:0] sram_we,
input [31:0] sram_addr,
input [31:0] sram_wdata,
output [63:0] sram_rdata,
// axi
input refresh,
input [CACHELINE_WD -1:0] cacheline_new,
output [CACHELINE_WD -1:0] cacheline_old
);
wire [31 :0] rdata_way0 [15:0];
wire [31 :0] rdata_way1 [15:0];
wire [TAG_WD -2:0] tag;
wire [5 :0] index;
wire [5 :0] offset;
reg [HIT_WD- 1:0] hit_r;
reg lru_r;
reg cached_r;
assign {tag,
index,
offset
} = sram_addr;
wire [15:0] bank_sel;
reg [15:0] bank_sel_r;
decoder_4_16 u_decoder_4_16(
.in (offset[5:2] ),
.out (bank_sel )
);
always @ (posedge clk) begin
if (reset) begin
hit_r <= 2'b0;
lru_r <= 1'b0;
cached_r <= 1'b1;
bank_sel_r <= 16'b0;
end
else begin
hit_r <= hit;
lru_r <= lru;
cached_r <= cached;
bank_sel_r <= bank_sel;
end
end
// data_bram_way0 begin
data_bram_bank bank0_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[0]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[31:0]:sram_wdata ), // 32
.douta (rdata_way0[0] ) // 32
);
data_bram_bank bank1_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[0]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[63:32]:sram_wdata ), // 32
.douta (rdata_way0[1] ) // 32
);
data_bram_bank bank2_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[2]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[95:64]:sram_wdata ), // 32
.douta (rdata_way0[2] ) // 32
);
data_bram_bank bank3_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[2]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[127:96]:sram_wdata ), // 32
.douta (rdata_way0[3] ) // 32
);
data_bram_bank bank4_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[4]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[159:128]:sram_wdata ), // 32
.douta (rdata_way0[4] ) // 32
);
data_bram_bank bank5_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[4]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[191:160]:sram_wdata ), // 32
.douta (rdata_way0[5] ) // 32
);
data_bram_bank bank6_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[6]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[223:192]:sram_wdata ), // 32
.douta (rdata_way0[6] ) // 32
);
data_bram_bank bank7_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[6]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[255:224]:sram_wdata ), // 32
.douta (rdata_way0[7] ) // 32
);
data_bram_bank bank8_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[8]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[287:256]:sram_wdata ), // 32
.douta (rdata_way0[8] ) // 32
);
data_bram_bank bank9_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[8]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[319:288]:sram_wdata ), // 32
.douta (rdata_way0[9] ) // 32
);
data_bram_bank bank10_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[10]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[351:320]:sram_wdata ), // 32
.douta (rdata_way0[10] ) // 32
);
data_bram_bank bank11_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[10]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[383:352]:sram_wdata ), // 32
.douta (rdata_way0[11] ) // 32
);
data_bram_bank bank12_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[12]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[415:384]:sram_wdata ), // 32
.douta (rdata_way0[12] ) // 32
);
data_bram_bank bank13_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[12]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[447:416]:sram_wdata ), // 32
.douta (rdata_way0[13] ) // 32
);
data_bram_bank bank14_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[14]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[479:448]:sram_wdata ), // 32
.douta (rdata_way0[14] ) // 32
);
data_bram_bank bank15_way0(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[14]&hit[0]|write_back ), // 1
.wea (refresh?lru?4'b0000:4'b1111:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[511:480]:sram_wdata ), // 32
.douta (rdata_way0[15] ) // 32
);
// data_bram_way0 end
// data_bram_way1 begin
data_bram_bank bank0_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[0]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[31:0]:sram_wdata ), // 32
.douta (rdata_way1[0] ) // 32
);
data_bram_bank bank1_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[0]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[63:32]:sram_wdata ), // 32
.douta (rdata_way1[1] ) // 32
);
data_bram_bank bank2_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[2]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[95:64]:sram_wdata ), // 32
.douta (rdata_way1[2] ) // 32
);
data_bram_bank bank3_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[2]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[127:96]:sram_wdata ), // 32
.douta (rdata_way1[3] ) // 32
);
data_bram_bank bank4_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[4]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[159:128]:sram_wdata ), // 32
.douta (rdata_way1[4] ) // 32
);
data_bram_bank bank5_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[4]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[191:160]:sram_wdata ), // 32
.douta (rdata_way1[5] ) // 32
);
data_bram_bank bank6_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[6]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[223:192]:sram_wdata ), // 32
.douta (rdata_way1[6] ) // 32
);
data_bram_bank bank7_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[6]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[255:224]:sram_wdata ), // 32
.douta (rdata_way1[7] ) // 32
);
data_bram_bank bank8_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[8]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[287:256]:sram_wdata ), // 32
.douta (rdata_way1[8] ) // 32
);
data_bram_bank bank9_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[8]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[319:288]:sram_wdata ), // 32
.douta (rdata_way1[9] ) // 32
);
data_bram_bank bank10_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[10]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[351:320]:sram_wdata ), // 32
.douta (rdata_way1[10] ) // 32
);
data_bram_bank bank11_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[10]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[383:352]:sram_wdata ), // 32
.douta (rdata_way1[11] ) // 32
);
data_bram_bank bank12_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[12]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[415:384]:sram_wdata ), // 32
.douta (rdata_way1[12] ) // 32
);
data_bram_bank bank13_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[12]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[447:416]:sram_wdata ), // 32
.douta (rdata_way1[13] ) // 32
);
data_bram_bank bank14_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[14]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[479:448]:sram_wdata ), // 32
.douta (rdata_way1[14] ) // 32
);
data_bram_bank bank15_way1(
.clka (clk ),
.ena (cached&refresh|sram_en&bank_sel[14]&hit[1]|write_back ), // 1
.wea (refresh?lru?4'b1111:4'b0000:write_back?4'b0000:sram_we), // 4
.addra (index ), // 7
.dina (refresh?cacheline_new[511:480]:sram_wdata ), // 32
.douta (rdata_way1[15] ) // 32
);
// data_bram_way1 end
wire [63:0] sram_rdata_way0,sram_rdata_way1;
assign sram_rdata_way0 = ~cached_r ? 64'b0 :
bank_sel_r[ 0] ? {rdata_way0[ 1],rdata_way0[ 0]} :
bank_sel_r[ 2] ? {rdata_way0[ 3],rdata_way0[ 2]} :
bank_sel_r[ 4] ? {rdata_way0[ 5],rdata_way0[ 4]} :
bank_sel_r[ 6] ? {rdata_way0[ 7],rdata_way0[ 6]} :
bank_sel_r[ 8] ? {rdata_way0[ 9],rdata_way0[ 8]} :
bank_sel_r[10] ? {rdata_way0[11],rdata_way0[10]} :
bank_sel_r[12] ? {rdata_way0[13],rdata_way0[12]} :
bank_sel_r[14] ? {rdata_way0[15],rdata_way0[14]} : 64'b0;
assign sram_rdata_way1 = ~cached_r ? 64'b0 :
bank_sel_r[ 0] ? {rdata_way1[ 1],rdata_way1[ 0]} :
bank_sel_r[ 2] ? {rdata_way1[ 3],rdata_way1[ 2]} :
bank_sel_r[ 4] ? {rdata_way1[ 5],rdata_way1[ 4]} :
bank_sel_r[ 6] ? {rdata_way1[ 7],rdata_way1[ 6]} :
bank_sel_r[ 8] ? {rdata_way1[ 9],rdata_way1[ 8]} :
bank_sel_r[10] ? {rdata_way1[11],rdata_way1[10]} :
bank_sel_r[12] ? {rdata_way1[13],rdata_way1[12]} :
bank_sel_r[14] ? {rdata_way1[15],rdata_way1[14]} : 64'b0;
assign sram_rdata = hit_r[0] ? sram_rdata_way0 :
hit_r[1] ? sram_rdata_way1 : 64'b0;
wire [CACHELINE_WD -1:0] cacheline_old_way0, cacheline_old_way1;
assign cacheline_old_way0 = {
rdata_way0[15],
rdata_way0[14],
rdata_way0[13],
rdata_way0[12],
rdata_way0[11],
rdata_way0[10],
rdata_way0[ 9],
rdata_way0[ 8],
rdata_way0[ 7],
rdata_way0[ 6],
rdata_way0[ 5],
rdata_way0[ 4],
rdata_way0[ 3],
rdata_way0[ 2],
rdata_way0[ 1],
rdata_way0[ 0]
};
assign cacheline_old_way1 = {
rdata_way1[15],
rdata_way1[14],
rdata_way1[13],
rdata_way1[12],
rdata_way1[11],
rdata_way1[10],
rdata_way1[ 9],
rdata_way1[ 8],
rdata_way1[ 7],
rdata_way1[ 6],
rdata_way1[ 5],
rdata_way1[ 4],
rdata_way1[ 3],
rdata_way1[ 2],
rdata_way1[ 1],
rdata_way1[ 0]
};
assign cacheline_old = lru_r ? cacheline_old_way1 : cacheline_old_way0;
endmodule

242
lacpu/rtl/cpu/cache_tag.v Normal file
View File

@@ -0,0 +1,242 @@
`default_nettype wire
module cache_tag_v5
#(
parameter HIT_WD = 2,
parameter TAG_WD = 21,
parameter INDEX_WD = 64
)
(
input clk,
input reset,
input flush,
output stallreq,
input cached,
input sram_en,
input [ 3:0] sram_we,
input [31:0] sram_addr,
input refresh,
output miss,
output [31:0] axi_raddr,
output write_back,
output [31:0] axi_waddr,
output [ 1:0] hit,
output lru
);
reg [TAG_WD -1:0] tag_way0 [INDEX_WD -1:0];
reg [TAG_WD -1:0] tag_way1 [INDEX_WD -1:0];
reg [INDEX_WD -1:0] lru_r;
wire [TAG_WD -2:0] tag;
wire [5:0] index;
wire [5:0] offset;
wire cached_v;
wire hit_way0;
wire hit_way1;
wire [31:0] axi_waddr_way0;
wire [31:0] axi_waddr_way1;
wire write_back_way0;
wire write_back_way1;
assign cached_v = cached;
assign {tag,
index,
offset
} = sram_addr;
// lru lru_r指向的即为最闲的那个
always @ (posedge clk) begin
if (reset) begin
lru_r <= 0;
end
else if (hit_way0 & ~hit_way1) begin
lru_r[index] <= 1'b1;
end
else if (~hit_way0 & hit_way1) begin
lru_r[index] <= 1'b0;
end
else if (refresh) begin
lru_r[index] <= ~lru_r[index];
end
end
// way0
always @ (posedge clk) begin
if (reset) begin
tag_way0[ 0] <= 21'b0;
tag_way0[ 1] <= 21'b0;
tag_way0[ 2] <= 21'b0;
tag_way0[ 3] <= 21'b0;
tag_way0[ 4] <= 21'b0;
tag_way0[ 5] <= 21'b0;
tag_way0[ 6] <= 21'b0;
tag_way0[ 7] <= 21'b0;
tag_way0[ 8] <= 21'b0;
tag_way0[ 9] <= 21'b0;
tag_way0[10] <= 21'b0;
tag_way0[11] <= 21'b0;
tag_way0[12] <= 21'b0;
tag_way0[13] <= 21'b0;
tag_way0[14] <= 21'b0;
tag_way0[15] <= 21'b0;
tag_way0[16] <= 21'b0;
tag_way0[17] <= 21'b0;
tag_way0[18] <= 21'b0;
tag_way0[19] <= 21'b0;
tag_way0[20] <= 21'b0;
tag_way0[21] <= 21'b0;
tag_way0[22] <= 21'b0;
tag_way0[23] <= 21'b0;
tag_way0[24] <= 21'b0;
tag_way0[25] <= 21'b0;
tag_way0[26] <= 21'b0;
tag_way0[27] <= 21'b0;
tag_way0[28] <= 21'b0;
tag_way0[29] <= 21'b0;
tag_way0[30] <= 21'b0;
tag_way0[31] <= 21'b0;
tag_way0[32] <= 21'b0;
tag_way0[33] <= 21'b0;
tag_way0[34] <= 21'b0;
tag_way0[35] <= 21'b0;
tag_way0[36] <= 21'b0;
tag_way0[37] <= 21'b0;
tag_way0[38] <= 21'b0;
tag_way0[39] <= 21'b0;
tag_way0[40] <= 21'b0;
tag_way0[41] <= 21'b0;
tag_way0[42] <= 21'b0;
tag_way0[43] <= 21'b0;
tag_way0[44] <= 21'b0;
tag_way0[45] <= 21'b0;
tag_way0[46] <= 21'b0;
tag_way0[47] <= 21'b0;
tag_way0[48] <= 21'b0;
tag_way0[49] <= 21'b0;
tag_way0[50] <= 21'b0;
tag_way0[51] <= 21'b0;
tag_way0[52] <= 21'b0;
tag_way0[53] <= 21'b0;
tag_way0[54] <= 21'b0;
tag_way0[55] <= 21'b0;
tag_way0[56] <= 21'b0;
tag_way0[57] <= 21'b0;
tag_way0[58] <= 21'b0;
tag_way0[59] <= 21'b0;
tag_way0[60] <= 21'b0;
tag_way0[61] <= 21'b0;
tag_way0[62] <= 21'b0;
tag_way0[63] <= 21'b0;
end
else if (refresh & (~lru_r[index])) begin
tag_way0[index] <= {cached_v, tag};
end
end
// way1
always @ (posedge clk) begin
if (reset) begin
tag_way1[ 0] <= 21'b0;
tag_way1[ 1] <= 21'b0;
tag_way1[ 2] <= 21'b0;
tag_way1[ 3] <= 21'b0;
tag_way1[ 4] <= 21'b0;
tag_way1[ 5] <= 21'b0;
tag_way1[ 6] <= 21'b0;
tag_way1[ 7] <= 21'b0;
tag_way1[ 8] <= 21'b0;
tag_way1[ 9] <= 21'b0;
tag_way1[10] <= 21'b0;
tag_way1[11] <= 21'b0;
tag_way1[12] <= 21'b0;
tag_way1[13] <= 21'b0;
tag_way1[14] <= 21'b0;
tag_way1[15] <= 21'b0;
tag_way1[16] <= 21'b0;
tag_way1[17] <= 21'b0;
tag_way1[18] <= 21'b0;
tag_way1[19] <= 21'b0;
tag_way1[20] <= 21'b0;
tag_way1[21] <= 21'b0;
tag_way1[22] <= 21'b0;
tag_way1[23] <= 21'b0;
tag_way1[24] <= 21'b0;
tag_way1[25] <= 21'b0;
tag_way1[26] <= 21'b0;
tag_way1[27] <= 21'b0;
tag_way1[28] <= 21'b0;
tag_way1[29] <= 21'b0;
tag_way1[30] <= 21'b0;
tag_way1[31] <= 21'b0;
tag_way1[32] <= 21'b0;
tag_way1[33] <= 21'b0;
tag_way1[34] <= 21'b0;
tag_way1[35] <= 21'b0;
tag_way1[36] <= 21'b0;
tag_way1[37] <= 21'b0;
tag_way1[38] <= 21'b0;
tag_way1[39] <= 21'b0;
tag_way1[40] <= 21'b0;
tag_way1[41] <= 21'b0;
tag_way1[42] <= 21'b0;
tag_way1[43] <= 21'b0;
tag_way1[44] <= 21'b0;
tag_way1[45] <= 21'b0;
tag_way1[46] <= 21'b0;
tag_way1[47] <= 21'b0;
tag_way1[48] <= 21'b0;
tag_way1[49] <= 21'b0;
tag_way1[50] <= 21'b0;
tag_way1[51] <= 21'b0;
tag_way1[52] <= 21'b0;
tag_way1[53] <= 21'b0;
tag_way1[54] <= 21'b0;
tag_way1[55] <= 21'b0;
tag_way1[56] <= 21'b0;
tag_way1[57] <= 21'b0;
tag_way1[58] <= 21'b0;
tag_way1[59] <= 21'b0;
tag_way1[60] <= 21'b0;
tag_way1[61] <= 21'b0;
tag_way1[62] <= 21'b0;
tag_way1[63] <= 21'b0;
end
else if (refresh & lru_r[index]) begin
tag_way1[index] <= {cached_v, tag};
end
end
assign lru = lru_r[index];
assign hit = {hit_way1, hit_way0};
assign hit_way0 = ~flush & cached_v & sram_en & ({1'b1,tag} == tag_way0[index]);
assign hit_way1 = ~flush & cached_v & sram_en & ({1'b1,tag} == tag_way1[index]);
assign miss = cached_v & sram_en & ~(hit_way0 | hit_way1) & ~flush;
assign stallreq = miss;
assign axi_raddr = cached_v ? {sram_addr[31:6], 6'b0} : sram_addr;
assign write_back = flush ? 1'b0 : lru ? write_back_way1 : write_back_way0;
assign write_back_way0 = cached_v & sram_en & miss & tag_way0[index][TAG_WD -1];
assign write_back_way1 = cached_v & sram_en & miss & tag_way1[index][TAG_WD -1];
assign axi_waddr = lru_r[index] ? axi_waddr_way1 : axi_waddr_way0;
assign axi_waddr_way0 = {tag_way0[index][TAG_WD -2:0],
index,
6'b0
};
assign axi_waddr_way1 = {tag_way1[index][TAG_WD -2:0],
index,
6'b0
};
endmodule

65
lacpu/rtl/cpu/dcache.v Normal file
View File

@@ -0,0 +1,65 @@
module dcache
#(
parameter HIT_WD = 2,
parameter LRU_WD = 1,
parameter CACHELINE_WD = 512
)
(
input clk,
input reset,
input data_sram_en,
input [ 3:0] data_sram_we,
input [31:0] data_sram_addr,
input [31:0] data_sram_wdata,
input dcache_refresh,
input dcache_uncached,
input [CACHELINE_WD -1:0] dcache_cacheline_new,
output stallreq_dcache,
output [31:0] data_sram_rdata,
output dcache_miss,
output [31:0] dcache_raddr,
output [31:0] dcache_waddr,
output dcache_write_back,
output [CACHELINE_WD -1:0] dcache_cacheline_old
);
wire [HIT_WD -1:0] dcache_hit;
wire [LRU_WD -1:0] dcache_lru;
cache_tag_v5 u_dcache_tag(
.clk (clk ),
.reset (reset ),
.flush (1'b0 ),
.stallreq (stallreq_dcache ),
.cached (~dcache_uncached ), // ? TODO from tlb
.sram_en (data_sram_en/* & ~d_refill & ~d_invalid & ~d_modify*/), // TODO!
.sram_we (data_sram_we ),
.sram_addr (data_sram_addr ), // _mmu ?
.refresh (dcache_refresh ),
.miss (dcache_miss ),
.axi_raddr (dcache_raddr ),
.write_back (dcache_write_back ),
.axi_waddr (dcache_waddr ),
.hit (dcache_hit ),
.lru (dcache_lru )
);
cache_data_v5 u_dcache_data(
.clk (clk ),
.reset (reset ),
.write_back (dcache_write_back ),
.hit (dcache_hit ),
.lru (dcache_lru ),
.cached (~dcache_uncached ), // ? from tlb
.sram_en (data_sram_en/* & ~d_refill & ~d_invalid & ~d_modify*/), // TODO!
.sram_we (data_sram_we ),
.sram_addr (data_sram_addr ), // _mmu ?
.sram_wdata (data_sram_wdata ),
.sram_rdata (data_sram_rdata ),
.refresh (dcache_refresh ),
.cacheline_new (dcache_cacheline_new ),
.cacheline_old (dcache_cacheline_old )
);
endmodule

63
lacpu/rtl/cpu/icache.v Normal file
View File

@@ -0,0 +1,63 @@
module icache
#(
parameter HIT_WD = 2,
parameter LRU_WD = 1,
parameter CACHELINE_WD = 512
)
(
input clk,
input reset,
input inst_sram_en,
input [ 3:0] inst_sram_we,
input [31:0] inst_sram_addr,
input [31:0] inst_sram_wdata,
input icache_refresh,
input [CACHELINE_WD -1:0] icache_cacheline_new,
output stallreq_icache,
output [31:0] inst_sram_rdata,
output icache_miss,
output [31:0] icache_raddr,
output [31:0] icache_waddr,
output [CACHELINE_WD -1:0] icache_cacheline_old
);
wire [HIT_WD -1:0] icache_hit;
wire [LRU_WD -1:0] icache_lru;
cache_tag_v5 u_icache_tag(
.clk (clk ),
.reset (reset ),
.flush (1'b0 ),
.stallreq (stallreq_icache ),
.cached (1'b1 ),
.sram_en (inst_sram_en/* & ~i_refill & ~i_invalid*/ ), // TODO!
.sram_we (inst_sram_we ),
.sram_addr (inst_sram_addr ), // _mmu ?
.refresh (icache_refresh ),
.miss (icache_miss ),
.axi_raddr (icache_raddr ),
.write_back (/*icache_write_back*/ ), // no use
.axi_waddr (icache_waddr ),
.hit (icache_hit ),
.lru (icache_lru )
);
cache_data_v5 u_icache_data(
.clk (clk ),
.reset (reset ),
.write_back (1'b0 ),
.hit (icache_hit ),
.lru (icache_lru ),
.cached (1'b1 ),
.sram_en (inst_sram_en/* & ~i_refill & ~i_invalid*/ ), // TODO!
.sram_we (inst_sram_we ),
.sram_addr (inst_sram_addr ),
.sram_wdata (inst_sram_wdata ),
.sram_rdata (inst_sram_rdata ),
.refresh (icache_refresh ),
.cacheline_new (icache_cacheline_new ),
.cacheline_old (icache_cacheline_old )
);
endmodule

21
lacpu/rtl/cpu/mmu.v Normal file
View File

@@ -0,0 +1,21 @@
module mmu (
input [31:0] addr_i,
output [31:0] addr_o,
output cache_v
);
wire [1:0] addr_head_i, addr_head_o;
assign addr_head_i = addr_i[31:30];
wire kseg0_l, kseg0_h, kseg1_l, kseg1_h;
assign kseg0_l = addr_head_i == 2'b00;
assign kseg0_h = addr_head_i == 2'b01;
assign kseg1_l = addr_head_i == 2'b10;
assign kseg1_h = addr_head_i == 2'b11;
wire other_seg;
assign other_seg = ~kseg0_l & ~kseg0_h & ~kseg1_l & ~kseg1_h;
assign addr_head_o = {2{kseg0_l}}&2'b00 | {2{kseg0_h}}&2'b01 | {2{kseg1_l}}&2'b10 | {2{kseg1_h}}&2'b11 | {2{other_seg}}&addr_head_i;
assign addr_o = {addr_head_o, addr_i[29:0]};
assign cache_v = ~(kseg0_l|kseg1_l|kseg1_h);
endmodule

167
lacpu/rtl/cpu/mycpu_core.v Normal file
View File

@@ -0,0 +1,167 @@
`default_nettype wire
module mycpu_core
#(
parameter FS_TO_DS_BUS_WD = 65,
parameter DS_TO_ES_BUS_WD = 301,
parameter ES_TO_MS_BUS_WD = 271,
parameter MS_TO_WS_BUS_WD = 102,
parameter WS_TO_RF_BUS_WD = 38,
parameter MS_TO_ES_BUS_WD = 38,
parameter WS_TO_ES_BUS_WD = 38,
parameter BR_BUS_WD = 33
)
(
input clk,
input resetn,
output timer_int,
// inst sram interface
output inst_sram_en,
output [ 3:0] inst_sram_we,
output [31:0] inst_sram_addr,
output [31:0] inst_sram_wdata,
input [31:0] inst_sram_rdata,
// data sram interface
output data_sram_en,
output [ 3:0] data_sram_we,
output [31:0] data_sram_addr,
output [31:0] data_sram_wdata,
input [31:0] data_sram_rdata,
// cache
input stallreq_dcache,
input stallreq_icache,
input stallreq_uncache,
// trace debug interface
output [31:0] debug_wb_pc,
output [ 3:0] debug_wb_rf_we,
output [ 4:0] debug_wb_rf_wnum,
output [31:0] debug_wb_rf_wdata
);
reg reset;
always @(posedge clk) reset <= ~resetn;
wire [FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus;
wire [DS_TO_ES_BUS_WD -1:0] ds_to_es_bus;
wire [ES_TO_MS_BUS_WD -1:0] es_to_ms_bus;
wire [MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus;
wire [WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus;
wire [MS_TO_ES_BUS_WD -1:0] ms_to_es_bus;
wire [WS_TO_ES_BUS_WD -1:0] ws_to_es_bus;
wire [BR_BUS_WD -1:0] br_bus;
wire flush;
wire stallreq_es;
wire stallreq_ds;
wire [ 5:0] stall;
wire except_en;
wire [31:0] new_pc;
wire [ 1:0] csr_plv;
wire csr_has_int;
wire stallreq_cache;
assign stallreq_cache = stallreq_dcache | stallreq_icache | stallreq_uncache;
if_stage if_stage(
.clk (clk ),
.reset (reset ),
.flush (flush ),
.stall (stall ),
.new_pc (new_pc ),
.timer_int (timer_int ),
.fs_to_ds_bus (fs_to_ds_bus ),
.br_bus (br_bus ),
.inst_sram_en (inst_sram_en ),
.inst_sram_we (inst_sram_we ),
.inst_sram_addr (inst_sram_addr ),
.inst_sram_wdata (inst_sram_wdata )
);
id_stage id_stage(
.clk (clk ),
.reset (reset ),
.flush (flush ),
.stall (stall ),
.br_taken (br_bus[32] ),
.stallreq_ds (stallreq_ds ),
.fs_to_ds_bus (fs_to_ds_bus ),
.pc_valid (inst_sram_en ),
.inst_sram_rdata (inst_sram_rdata ),
.csr_plv (csr_plv ),
.csr_has_int (csr_has_int ),
.ws_to_rf_bus (ws_to_rf_bus ),
.ds_to_es_bus (ds_to_es_bus )
);
exe_stage exe_stage(
.clk (clk ),
.reset (reset ),
.flush (flush ),
.stall (stall ),
.stallreq_es (stallreq_es ),
.ds_to_es_bus (ds_to_es_bus ),
.es_to_ms_bus (es_to_ms_bus ),
.ms_to_es_bus (ms_to_es_bus ),
.ws_to_es_bus (ws_to_es_bus ),
.br_bus (br_bus ),
.data_sram_en (data_sram_en ),
.data_sram_we (data_sram_we ),
.data_sram_addr (data_sram_addr ),
.data_sram_wdata (data_sram_wdata )
);
mem_stage mem_stage(
.clk (clk ),
.reset (reset ),
.flush (flush ),
.stall (stall ),
.except_en (except_en ),
.new_pc (new_pc ),
.csr_plv (csr_plv ),
.csr_has_int (csr_has_int ),
.es_to_ms_bus (es_to_ms_bus ),
.ms_to_es_bus (ms_to_es_bus ),
.ms_to_ws_bus (ms_to_ws_bus ),
.data_sram_rdata (data_sram_rdata )
);
wb_stage wb_stage(
.clk (clk ),
.reset (reset ),
.flush (flush ),
.stall (stall ),
.ms_to_ws_bus (ms_to_ws_bus ),
.ws_to_rf_bus (ws_to_rf_bus ),
.ws_to_es_bus (ws_to_es_bus ),
.debug_wb_pc (debug_wb_pc ),
.debug_wb_rf_we (debug_wb_rf_we ),
.debug_wb_rf_wnum (debug_wb_rf_wnum ),
.debug_wb_rf_wdata (debug_wb_rf_wdata)
);
pip_ctrl pip_ctrl(
.reset (reset ),
.except_en (except_en ),
.stallreq_ds (stallreq_ds ),
.stallreq_es (stallreq_es ),
.stallreq_axi (1'b0 ), // TODO!
.stallreq_cache (stallreq_cache ),
.flush (flush ),
.stall (stall )
);
endmodule

View File

@@ -1,33 +1,69 @@
`default_nettype wire
module mycpu_top
#(
parameter FS_TO_DS_BUS_WD = 65,
parameter DS_TO_ES_BUS_WD = 301,
parameter ES_TO_MS_BUS_WD = 271,
parameter MS_TO_WS_BUS_WD = 102,
parameter WS_TO_RF_BUS_WD = 38,
parameter MS_TO_ES_BUS_WD = 38,
parameter WS_TO_ES_BUS_WD = 38,
parameter BR_BUS_WD = 33
parameter HIT_WD = 2,
parameter LRU_WD = 1,
parameter CACHELINE_WD = 512
)
(
input clk,
input resetn,
input aclk,
input aresetn,
output timer_int,
// inst sram interface
output inst_sram_en,
output [ 3:0] inst_sram_we,
output [31:0] inst_sram_addr,
output [31:0] inst_sram_wdata,
input [31:0] inst_sram_rdata,
// data sram interface
output data_sram_en,
output [ 3:0] data_sram_we,
output [31:0] data_sram_addr,
output [31:0] data_sram_wdata,
input [31:0] data_sram_rdata,
output [ 3:0] arid,
output [31:0] araddr,
output [ 3:0] arlen,
output [ 2:0] arsize,
output [ 1:0] arburst,
output [ 1:0] arlock,
output [ 3:0] arcache,
output [ 2:0] arprot,
output arvalid,
input arready,
input [ 3:0] rid,
input [31:0] rdata,
input [ 1:0] rresp,
input rlast,
input rvalid,
output rready,
output [ 3:0] awid,
output [31:0] awaddr,
output [ 3:0] awlen,
output [ 2:0] awsize,
output [ 1:0] awburst,
output [ 1:0] awlock,
output [ 3:0] awcache,
output [ 2:0] awprot,
output awvalid,
input awready,
output [ 3:0] wid,
output [31:0] wdata,
output [ 3:0] wstrb,
output wlast,
output wvalid,
input wready,
input [ 3:0] bid,
input [ 1:0] bresp,
input bvalid,
output bready,
// // inst sram interface
// output inst_sram_en,
// output [ 3:0] inst_sram_we,
// output [31:0] inst_sram_addr,
// output [31:0] inst_sram_wdata,
// input [31:0] inst_sram_rdata,
// // data sram interface
// output data_sram_en,
// output [ 3:0] data_sram_we,
// output [31:0] data_sram_addr,
// output [31:0] data_sram_wdata,
// input [31:0] data_sram_rdata,
// trace debug interface
output [31:0] debug_wb_pc,
output [ 3:0] debug_wb_rf_we,
@@ -35,122 +71,239 @@ module mycpu_top
output [31:0] debug_wb_rf_wdata
);
reg reset;
always @(posedge clk) reset <= ~resetn;
wire inst_sram_en;
wire [ 3:0] inst_sram_we;
wire [31:0] inst_sram_addr;
wire [31:0] inst_sram_wdata;
wire [31:0] inst_sram_rdata;
wire [FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus;
wire [DS_TO_ES_BUS_WD -1:0] ds_to_es_bus;
wire [ES_TO_MS_BUS_WD -1:0] es_to_ms_bus;
wire [MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus;
wire [WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus;
wire data_sram_en;
wire [ 3:0] data_sram_we;
wire [31:0] data_sram_addr;
wire [31:0] data_sram_wdata;
wire [31:0] data_sram_rdata;
wire [MS_TO_ES_BUS_WD -1:0] ms_to_es_bus;
wire [WS_TO_ES_BUS_WD -1:0] ws_to_es_bus;
wire clk;
wire resetn;
wire [BR_BUS_WD -1:0] br_bus;
assign clk = aclk;
assign resetn = aresetn;
wire flush;
wire stallreq_es;
wire stallreq_ds;
wire [ 5:0] stall;
wire except_en;
wire [31:0] new_pc;
// icache tag
wire icache_cached;
wire icache_uncached;
wire icache_refresh;
wire icache_miss;
wire [31:0] icache_raddr;
//wire icache_write_back;
wire [31:0] icache_waddr;
// icache data
wire [CACHELINE_WD -1:0] icache_cacheline_new;
wire [CACHELINE_WD -1:0] icache_cacheline_old;
wire [ 1:0] csr_plv;
wire csr_has_int;
if_stage if_stage(
.clk (clk ),
.reset (reset ),
.flush (flush ),
.stall (stall ),
.new_pc (new_pc ),
.timer_int (timer_int ),
.fs_to_ds_bus (fs_to_ds_bus ),
.br_bus (br_bus ),
.inst_sram_en (inst_sram_en ),
.inst_sram_we (inst_sram_we ),
.inst_sram_addr (inst_sram_addr ),
.inst_sram_wdata (inst_sram_wdata )
// dcache tag
wire dcache_cached;
wire dcache_uncached;
wire dcache_refresh;
wire dcache_miss;
wire [31:0] dcache_raddr;
wire dcache_write_back;
wire [31:0] dcache_waddr;
// dcache data
wire [CACHELINE_WD -1:0] dcache_cacheline_new;
wire [CACHELINE_WD -1:0] dcache_cacheline_old;
// uncache tag
wire uncache_refresh;
wire uncache_en;
wire [ 3:0] uncache_we;
wire [31:0] uncache_addr;
wire [31:0] uncache_wdata;
// uncache data
wire [31:0] uncache_rdata;
wire [31:0] data_sram_addr_mmu;
wire [31:0] dcache_temp_rdata;
wire [31:0] uncache_temp_rdata;
wire stallreq_icache;
wire stallreq_dcache;
wire stallreq_uncache;
mycpu_core mycpu_core(
.clk (clk ),
.resetn (resetn ),
.inst_sram_en (inst_sram_en ),
.inst_sram_we (inst_sram_we ),
.inst_sram_addr (inst_sram_addr ),
.inst_sram_wdata (inst_sram_wdata ),
.inst_sram_rdata (inst_sram_rdata ),
.data_sram_en (data_sram_en ),
.data_sram_we (data_sram_we ),
.data_sram_addr (data_sram_addr ),
.data_sram_wdata (data_sram_wdata ),
.data_sram_rdata (data_sram_rdata ),
.stallreq_dcache (stallreq_dcache ),
.stallreq_icache (stallreq_icache ),
.stallreq_uncache (stallreq_uncache ),
.debug_wb_pc (debug_wb_pc ),
.debug_wb_rf_we (debug_wb_rf_we ),
.debug_wb_rf_wnum (debug_wb_rf_wnum ),
.debug_wb_rf_wdata (debug_wb_rf_wdata )
);
id_stage id_stage(
.clk (clk ),
.reset (reset ),
.flush (flush ),
.stall (stall ),
.br_taken (br_bus[32] ),
.stallreq_ds (stallreq_ds ),
.fs_to_ds_bus (fs_to_ds_bus ),
.pc_valid (inst_sram_en ),
.inst_sram_rdata (inst_sram_rdata ),
.csr_plv (csr_plv ),
.csr_has_int (csr_has_int ),
.ws_to_rf_bus (ws_to_rf_bus ),
.ds_to_es_bus (ds_to_es_bus )
icache icache(
.clk (clk ),
.reset (~resetn ),
.inst_sram_en (inst_sram_en ),
.inst_sram_we (inst_sram_we ),
.inst_sram_addr (inst_sram_addr ),
.inst_sram_wdata (inst_sram_wdata ),
.icache_refresh (icache_refresh ),
.icache_cacheline_new (icache_cacheline_new),
.stallreq_icache (stallreq_icache ),
.inst_sram_rdata (inst_sram_rdata ),
.icache_miss (icache_miss ),
.icache_raddr (icache_raddr ),
.icache_waddr (icache_waddr ),
.icache_cacheline_old (icache_cacheline_old)
);
exe_stage exe_stage(
.clk (clk ),
.reset (reset ),
.flush (flush ),
.stall (stall ),
.stallreq_es (stallreq_es ),
.ds_to_es_bus (ds_to_es_bus ),
.es_to_ms_bus (es_to_ms_bus ),
.ms_to_es_bus (ms_to_es_bus ),
.ws_to_es_bus (ws_to_es_bus ),
.br_bus (br_bus ),
.data_sram_en (data_sram_en ),
.data_sram_we (data_sram_we ),
.data_sram_addr (data_sram_addr ),
.data_sram_wdata (data_sram_wdata )
dcache dcache(
.clk (clk ),
.reset (~resetn ),
.data_sram_en (data_sram_en ),
.data_sram_we (data_sram_we ),
.data_sram_addr (data_sram_addr_mmu ),
.data_sram_wdata (data_sram_wdata ),
.dcache_refresh (dcache_refresh ),
.dcache_uncached (dcache_uncached ),
.dcache_cacheline_new (dcache_cacheline_new),
.stallreq_dcache (stallreq_dcache ),
.data_sram_rdata (dcache_temp_rdata ),
.dcache_miss (dcache_miss ),
.dcache_raddr (dcache_raddr ),
.dcache_waddr (dcache_waddr ),
.dcache_write_back (dcache_write_back ),
.dcache_cacheline_old (dcache_cacheline_old)
);
mem_stage mem_stage(
.clk (clk ),
.reset (reset ),
.flush (flush ),
.stall (stall ),
.except_en (except_en ),
.new_pc (new_pc ),
.csr_plv (csr_plv ),
.csr_has_int (csr_has_int ),
.es_to_ms_bus (es_to_ms_bus ),
.ms_to_es_bus (ms_to_es_bus ),
.ms_to_ws_bus (ms_to_ws_bus ),
.data_sram_rdata (data_sram_rdata )
uncache uncache(
.clk (clk ),
.resetn (resetn ),
.stallreq (stallreq_uncache ),
.conf_en (data_sram_en & ~dcache_cached ),
.conf_we (data_sram_we ),
.conf_addr (data_sram_addr_mmu ), // _mmu ?
.conf_wdata (data_sram_wdata ),
.conf_rdata (uncache_temp_rdata ),
.axi_en (uncache_en ),
.axi_wsel (uncache_we ),
.axi_addr (uncache_addr ),
.axi_wdata (uncache_wdata ),
.reload (uncache_refresh ),
.axi_rdata (uncache_rdata )
);
wb_stage wb_stage(
.clk (clk ),
.reset (reset ),
.flush (flush ),
.stall (stall ),
reg dcache_cached_r;
//assign dcache_cached = ~dcache_uncached;
assign dcache_uncached = ~dcache_cached;
always @ (posedge clk) begin
dcache_cached_r <= dcache_cached;
end
assign data_sram_rdata = dcache_cached_r ? dcache_temp_rdata : uncache_temp_rdata;
.ms_to_ws_bus (ms_to_ws_bus ),
.ws_to_rf_bus (ws_to_rf_bus ),
.ws_to_es_bus (ws_to_es_bus ),
.debug_wb_pc (debug_wb_pc ),
.debug_wb_rf_we (debug_wb_rf_we ),
.debug_wb_rf_wnum (debug_wb_rf_wnum ),
.debug_wb_rf_wdata (debug_wb_rf_wdata)
// mmu u_inst_mmu(
// .addr_i (inst_sram_addr ),
// .addr_o (inst_sram_addr_mmu ),
// .cache_v (icache_cached )
// );
mmu data_mmu(
.addr_i (data_sram_addr ),
.addr_o (data_sram_addr_mmu ),
.cache_v (dcache_cached )
);
pip_ctrl pip_ctrl(
.reset (reset ),
.except_en (except_en ),
.stallreq_ds (stallreq_ds ),
.stallreq_es (stallreq_es ),
.stallreq_axi (1'b0 ), // TODO!
.flush (flush ),
.stall (stall )
// cache signal from tlb
// begin
//assign dcache_uncached = 1'b0;
// end
axi_ctrl_v5 axi_ctrl(
.clk (clk ),
.reset (~resetn ),
.icache_re (icache_miss ),
.icache_raddr (icache_raddr ),
.icache_cacheline_new (icache_cacheline_new ),
.icache_we (1'b0 ),
.icache_waddr (icache_waddr ),
.icache_cacheline_old (icache_cacheline_old ),
.icache_refresh (icache_refresh ),
.dcache_re (dcache_miss ),
.dcache_raddr (dcache_raddr ),
.dcache_cacheline_new (dcache_cacheline_new ),
.dcache_we (dcache_write_back ),
.dcache_waddr (dcache_waddr ),
.dcache_cacheline_old (dcache_cacheline_old ),
.dcache_refresh (dcache_refresh ),
.uncache_en (uncache_en ),
.uncache_we (uncache_we ),
.uncache_addr (uncache_addr ),
.uncache_wdata (uncache_wdata ),
.uncache_rdata (uncache_rdata ),
.uncache_refresh (uncache_refresh ),
.arid (arid ),
.araddr (araddr ),
.arlen (arlen ),
.arsize (arsize ),
.arburst (arburst ),
.arlock (arlock ),
.arcache (arcache ),
.arprot (arprot ),
.arvalid (arvalid ),
.arready (arready ),
.rid (rid ),
.rdata (rdata ),
.rresp (rresp ),
.rlast (rlast ),
.rvalid (rvalid ),
.rready (rready ),
.awid (awid ),
.awaddr (awaddr ),
.awlen (awlen ),
.awsize (awsize ),
.awburst (awburst ),
.awlock (awlock ),
.awcache (awcache ),
.awprot (awprot ),
.awvalid (awvalid ),
.awready (awready ),
.wid (wid ),
.wdata (wdata ),
.wstrb (wstrb ),
.wlast (wlast ),
.wvalid (wvalid ),
.wready (wready ),
.bid (bid ),
.bresp (bresp ),
.bvalid (bvalid ),
.bready (bready )
);
endmodule

View File

@@ -5,6 +5,7 @@ module pip_ctrl(
input stallreq_ds,
input stallreq_es,
input stallreq_axi,
input stallreq_cache,
output reg flush,
output reg [`StallBus-1:0] stall
);
@@ -36,6 +37,10 @@ module pip_ctrl(
flush = 0;
stall = `StallBus'b011111;
end
else if(stallreq_cache) begin
flush = 0;
stall = `StallBus'b111111;
end
else begin
flush = 0;
stall = `StallBus'b000000;

131
lacpu/rtl/cpu/uncache.v Normal file
View File

@@ -0,0 +1,131 @@
`default_nettype wire
module uncache
#(
parameter STAGE_WD = 4,
parameter WAIT = 4'b1000,
parameter IDLE = 4'b0001,
parameter BUFFER = 4'b0010
)
(
input clk,
input resetn,
output stallreq,
input conf_en,
input [ 3:0] conf_we,
input [31:0] conf_addr,
input [31:0] conf_wdata,
output reg [31:0] conf_rdata,
output reg axi_en, // en
output reg [ 3:0] axi_wsel, // we
output reg [31:0] axi_addr, // addr
output reg [31:0] axi_wdata,
input reload,
input [31:0] axi_rdata
);
reg valid;
reg finish;
reg buffer_valid;
reg [STAGE_WD -1:0] stage;
wire conf_rd_req;
wire conf_wr_req;
assign conf_rd_req = conf_en & ~valid & ~(|conf_we);
assign conf_wr_req = conf_en & ~valid & (|conf_we);
assign stallreq = conf_rd_req & ~valid | conf_wr_req & buffer_valid & ~valid | stage[3];
always @ (posedge clk) begin
if (!resetn) begin
valid <= 1'b0;
end
else if (finish) begin
valid <= 1'b1;
end
else begin
valid <= 1'b0;
end
end
// assign rd_req = conf_en & ~valid & ~(|conf_we);
// assign rd_addr = conf_addr;
// assign wr_req = conf_en & ~valid & (|conf_we);
// assign wr_wstrb = conf_we;
// assign wr_addr = conf_addr;
// assign wr_data = conf_wdata;
always @ (posedge clk) begin
if (!resetn) begin
conf_rdata <= 32'b0;
end
else if (reload) begin
conf_rdata <= axi_rdata;
end
end
always @ (posedge clk) begin
if (!resetn) begin
buffer_valid <= 1'b0;
stage <= {{(STAGE_WD-1){1'b0}}, 1'b1};
finish <= 1'b0;
axi_en <= 1'b0;
axi_wsel <= 4'b0;
axi_addr <= 32'b0;
axi_wdata <= 32'b0;
end
else begin
case(1'b1)
stage[0]:begin
if (conf_rd_req & ~buffer_valid) begin
axi_en <= 1'b1;
axi_wsel <= conf_we;
axi_addr <= conf_addr;
axi_wdata <= conf_wdata;
stage <= WAIT;
end
else if (conf_wr_req & ~buffer_valid) begin
axi_en <= 1'b1;
axi_wsel <= conf_we;
axi_addr <= conf_addr;
axi_wdata <= conf_wdata;
buffer_valid <= 1'b1;
// finish <= 1'b1;
stage <= BUFFER;
end
end
stage[1]:begin //BUFFER
// finish <= 1'b0;
if (reload) begin
buffer_valid <= 1'b0;
axi_en <= 1'b0;
axi_wsel <= 4'b0;
axi_addr <= 32'b0;
axi_wdata <= 32'b0;
stage <= IDLE;
end
end
stage[3]:begin
if (reload) begin
axi_en <= 1'b0;
axi_wsel <= 4'b0;
axi_addr <= 32'b0;
axi_wdata <= 32'b0;
finish <= 1'b1;
end
else if (finish) begin
finish <= 1'b0;
stage <= {{(STAGE_WD-1){1'b0}}, 1'b1};
end
end
default:begin
stage <= {{(STAGE_WD-1){1'b0}}, 1'b1};
end
endcase
end
end
endmodule

View File

@@ -60,9 +60,9 @@ module wb_stage
end
assign debug_wb_pc = ws_pc;
assign debug_wb_rf_we = {4{reg_we}};
assign debug_wb_rf_wnum = dest;
assign debug_wb_rf_wdata = ms_final_result;
assign debug_wb_pc = stall[5] ? 0 : ws_pc;
assign debug_wb_rf_we = stall[5] ? 0 : {4{reg_we}};
assign debug_wb_rf_wnum = stall[5] ? 0 : dest;
assign debug_wb_rf_wdata = stall[5] ? 0 : ms_final_result;
endmodule