[Modified] Switch soc_top&board to axi&xc7a200t
This commit is contained in:
99
lacpu/rtl/mycpu/alu.v
Normal file
99
lacpu/rtl/mycpu/alu.v
Normal file
@@ -0,0 +1,99 @@
|
||||
module alu(
|
||||
input [11:0] alu_op ,
|
||||
input [31:0] alu_src1 ,
|
||||
input [31:0] alu_src2 ,
|
||||
output [31:0] alu_result
|
||||
);
|
||||
|
||||
wire op_add;
|
||||
wire op_sub;
|
||||
wire op_lui;
|
||||
wire op_slt;
|
||||
wire op_sltu;
|
||||
wire op_and;
|
||||
wire op_or;
|
||||
wire op_nor;
|
||||
wire op_xor;
|
||||
wire op_sll;
|
||||
wire op_srl;
|
||||
wire op_sra;
|
||||
|
||||
|
||||
assign op_add = alu_op[ 0];
|
||||
assign op_sub = alu_op[ 1];
|
||||
assign op_slt = alu_op[ 2];
|
||||
assign op_sltu = alu_op[ 3];
|
||||
assign op_and = alu_op[ 4];
|
||||
assign op_nor = alu_op[ 5];
|
||||
assign op_or = alu_op[ 6];
|
||||
assign op_xor = alu_op[ 7];
|
||||
assign op_sll = alu_op[ 8];
|
||||
assign op_srl = alu_op[ 9];
|
||||
assign op_sra = alu_op[10];
|
||||
assign op_lui = alu_op[11];
|
||||
|
||||
|
||||
wire [31:0] add_sub_result;
|
||||
wire [31:0] slt_result;
|
||||
wire [31:0] sltu_result;
|
||||
wire [31:0] and_result;
|
||||
wire [31:0] nor_result;
|
||||
wire [31:0] or_result;
|
||||
wire [31:0] xor_result;
|
||||
wire [31:0] lui_result;
|
||||
wire [31:0] sll_result;
|
||||
wire [63:0] sr64_result;
|
||||
wire [31:0] sr_result;
|
||||
|
||||
// 32-bit adder
|
||||
wire [31:0] adder_a;
|
||||
wire [31:0] adder_b;
|
||||
wire adder_cin;
|
||||
wire [31:0] adder_result;
|
||||
wire adder_cout;
|
||||
|
||||
assign adder_a = alu_src1;
|
||||
assign adder_b = (op_sub | op_slt | op_sltu) ? ~alu_src2 : alu_src2;
|
||||
assign adder_cin = (op_sub | op_slt | op_sltu) ? 1'b1 : 1'b0;
|
||||
assign {adder_cout, adder_result} = adder_a + adder_b + adder_cin;
|
||||
|
||||
// ADD, SUB result
|
||||
assign add_sub_result = adder_result;
|
||||
|
||||
// SLT result
|
||||
assign slt_result[31:1] = 31'b0;
|
||||
assign slt_result[0] = (alu_src1[31] & ~alu_src2[31])
|
||||
| ((alu_src1[31] ~^ alu_src2[31]) & adder_result[31]);
|
||||
|
||||
// SLTU result
|
||||
assign sltu_result[31:1] = 31'b0;
|
||||
assign sltu_result[0] = ~adder_cout;
|
||||
|
||||
// bitwise operation
|
||||
assign and_result = alu_src1 & alu_src2;
|
||||
assign or_result = alu_src1 | alu_src2;
|
||||
assign nor_result = ~or_result;
|
||||
assign xor_result = alu_src1 ^ alu_src2;
|
||||
assign lui_result = alu_src2;
|
||||
|
||||
// SLL result
|
||||
assign sll_result = alu_src1 << alu_src2[4:0];
|
||||
|
||||
// SRL, SRA result
|
||||
assign sr64_result = {{32{op_sra & alu_src1[31]}}, alu_src1[31:0]} >> alu_src2[4:0];
|
||||
|
||||
assign sr_result = sr64_result[31:0];
|
||||
|
||||
// final result mux
|
||||
assign alu_result = ({32{op_add|op_sub}} & add_sub_result)
|
||||
| ({32{op_slt }} & slt_result)
|
||||
| ({32{op_sltu }} & sltu_result)
|
||||
| ({32{op_and }} & and_result)
|
||||
| ({32{op_nor }} & nor_result)
|
||||
| ({32{op_or }} & or_result)
|
||||
| ({32{op_xor }} & xor_result)
|
||||
| ({32{op_lui }} & lui_result)
|
||||
| ({32{op_sll }} & sll_result)
|
||||
| ({32{op_srl|op_sra}} & sr_result);
|
||||
|
||||
endmodule
|
||||
428
lacpu/rtl/mycpu/axi_ctrl.v
Normal file
428
lacpu/rtl/mycpu/axi_ctrl.v
Normal 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
|
||||
56
lacpu/rtl/mycpu/bru.v
Normal file
56
lacpu/rtl/mycpu/bru.v
Normal file
@@ -0,0 +1,56 @@
|
||||
module bru(
|
||||
input [31:0] pc,
|
||||
input [31:0] rj_value,
|
||||
input [31:0] rkd_value,
|
||||
input [31:0] imm,
|
||||
|
||||
input [ 8:0] branch_op,
|
||||
|
||||
output br_taken,
|
||||
output [31:0] br_target
|
||||
);
|
||||
|
||||
wire inst_jirl;
|
||||
wire inst_b;
|
||||
wire inst_bl;
|
||||
wire inst_beq;
|
||||
wire inst_bne;
|
||||
wire inst_blt;
|
||||
wire inst_bge;
|
||||
wire inst_bltu;
|
||||
wire inst_bgeu;
|
||||
|
||||
wire rj_eq_rd;
|
||||
wire rj_lt_rd;
|
||||
wire rj_ltu_rd;
|
||||
|
||||
assign {inst_beq,
|
||||
inst_bne,
|
||||
inst_blt,
|
||||
inst_bge,
|
||||
inst_bltu,
|
||||
inst_bgeu,
|
||||
inst_jirl,
|
||||
inst_bl,
|
||||
inst_b
|
||||
} = branch_op;
|
||||
|
||||
assign rj_eq_rd = (rj_value == rkd_value);
|
||||
assign rj_ltu_rd = (rj_value < rkd_value);
|
||||
assign rj_lt_rd = (rj_value[31] && ~rkd_value[31]) ? 1'b1 :
|
||||
(~rj_value[31] && rkd_value[31]) ? 1'b0 :
|
||||
rj_ltu_rd;
|
||||
assign br_taken = ( inst_beq && rj_eq_rd
|
||||
|| inst_bne && !rj_eq_rd
|
||||
|| inst_blt && rj_lt_rd
|
||||
|| inst_bge && !rj_lt_rd
|
||||
|| inst_bltu && rj_ltu_rd
|
||||
|| inst_bgeu && !rj_ltu_rd
|
||||
|| inst_jirl
|
||||
|| inst_bl
|
||||
|| inst_b
|
||||
);
|
||||
|
||||
assign br_target = ({32{inst_beq|inst_bne|inst_bl|inst_b|inst_blt|inst_bge|inst_bltu|inst_bgeu}} & (pc + imm))
|
||||
| ({32{inst_jirl}} & (rj_value + imm));
|
||||
endmodule
|
||||
792
lacpu/rtl/mycpu/cache_data.v
Normal file
792
lacpu/rtl/mycpu/cache_data.v
Normal 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/mycpu/cache_tag.v
Normal file
242
lacpu/rtl/mycpu/cache_tag.v
Normal 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
|
||||
105
lacpu/rtl/mycpu/csr.hv
Normal file
105
lacpu/rtl/mycpu/csr.hv
Normal file
@@ -0,0 +1,105 @@
|
||||
`define CRMD_ADDR 14'h0
|
||||
`define PRMD_ADDR 14'h1
|
||||
`define EUEN_ADDR 14'h2
|
||||
`define ECFG_ADDR 14'h4
|
||||
`define ESTAT_ADDR 14'h5
|
||||
`define ERA_ADDR 14'h6
|
||||
`define BADV_ADDR 14'h7
|
||||
`define EENTRY_ADDR 14'hc
|
||||
`define TLBIDX_ADDR 14'h10
|
||||
`define TLBEHI_ADDR 14'h11
|
||||
`define TLBELO0_ADDR 14'h12
|
||||
`define TLBELO1_ADDR 14'h13
|
||||
`define ASID_ADDR 14'h18
|
||||
`define PGDL_ADDR 14'h19
|
||||
`define PGDH_ADDR 14'h1a
|
||||
`define PGD_ADDR 14'h1b
|
||||
`define CPUID_ADDR 14'h20
|
||||
`define SAVE0_ADDR 14'h30
|
||||
`define SAVE1_ADDR 14'h31
|
||||
`define SAVE2_ADDR 14'h32
|
||||
`define SAVE3_ADDR 14'h33
|
||||
`define TID_ADDR 14'h40
|
||||
`define TCFG_ADDR 14'h41
|
||||
`define TVAL_ADDR 14'h42
|
||||
`define CNTC_ADDR 14'h43
|
||||
`define TICLR_ADDR 14'h44
|
||||
`define LLBCTL_ADDR 14'h60
|
||||
`define TLBRENTRY_ADDR 14'h88
|
||||
`define CTAG_ADDR 14'h98
|
||||
`define DMW0_ADDR 14'h180
|
||||
`define DMW1_ADDR 14'h181
|
||||
|
||||
//CRMD
|
||||
`define PLV 1:0
|
||||
`define IE 2
|
||||
`define DA 3
|
||||
`define PG 4
|
||||
`define DATF 6:5
|
||||
`define DATM 8:7
|
||||
//PRMD
|
||||
`define PPLV 1:0
|
||||
`define PIE 2
|
||||
//ECTL
|
||||
`define LIE 12:0
|
||||
`define LIE_1 9:0
|
||||
`define LIE_2 12:11
|
||||
//ESTAT
|
||||
`define IS 12:0
|
||||
`define ECODE 21:16
|
||||
`define ESUBCODE 30:22
|
||||
//TLBIDX
|
||||
`define INDEX 4:0
|
||||
`define PS 29:24
|
||||
`define NE 31
|
||||
//TLBEHI
|
||||
`define VPPN 31:13
|
||||
//TLBELO
|
||||
`define TLB_V 0
|
||||
`define TLB_D 1
|
||||
`define TLB_PLV 3:2
|
||||
`define TLB_MAT 5:4
|
||||
`define TLB_G 6
|
||||
`define TLB_PPN 31:8
|
||||
`define TLB_PPN_EN 27:8 //todo
|
||||
//ASID
|
||||
`define TLB_ASID 9:0
|
||||
//CPUID
|
||||
`define COREID 8:0
|
||||
//LLBCTL
|
||||
`define ROLLB 0
|
||||
`define WCLLB 1
|
||||
`define KLO 2
|
||||
//TCFG
|
||||
`define EN 0
|
||||
`define PERIODIC 1
|
||||
`define INITVAL 31:2
|
||||
//TICLR
|
||||
`define CLR 0
|
||||
//TLBRENTRY
|
||||
`define TLBRENTRY_PA 31:6
|
||||
//DMW
|
||||
`define PLV0 0
|
||||
`define PLV3 3
|
||||
`define DMW_MAT 5:4
|
||||
`define PSEG 27:25
|
||||
`define VSEG 31:29
|
||||
//PGDL PGDH PGD
|
||||
`define BASE 31:12
|
||||
|
||||
`define ECODE_INT 6'h0
|
||||
`define ECODE_PIL 6'h1
|
||||
`define ECODE_PIS 6'h2
|
||||
`define ECODE_PIF 6'h3
|
||||
`define ECODE_PME 6'h4
|
||||
`define ECODE_PPI 6'h7
|
||||
`define ECODE_ADEF 6'h8
|
||||
`define ECODE_ALE 6'h9
|
||||
`define ECODE_SYS 6'hb
|
||||
`define ECODE_BRK 6'hc
|
||||
`define ECODE_INE 6'hd
|
||||
`define ECODE_IPE 6'he
|
||||
`define ECODE_FPD 6'hf
|
||||
`define ECODE_TLBR 6'h3f
|
||||
|
||||
`define ESUBCODE_ADEF 9'h0
|
||||
355
lacpu/rtl/mycpu/csr.v
Normal file
355
lacpu/rtl/mycpu/csr.v
Normal file
@@ -0,0 +1,355 @@
|
||||
`include "csr.hv"
|
||||
module csr(
|
||||
input clk,
|
||||
input reset,
|
||||
input stall,
|
||||
|
||||
input [31:0] pc,
|
||||
input [31:0] src1,
|
||||
input stallreq_axi,
|
||||
|
||||
input [31:0] error_va,
|
||||
|
||||
input csr_we,
|
||||
input [63:0] csr_vec,
|
||||
input [ 6:0] csr_op,
|
||||
input [13:0] csr_addr,
|
||||
input csr_wdata_sel,
|
||||
input [31:0] csr_wdata,
|
||||
output [31:0] csr_rdata,
|
||||
|
||||
output except_en,
|
||||
output [31:0] new_pc,
|
||||
|
||||
output [ 1:0] plv_out,
|
||||
output has_int_out
|
||||
);
|
||||
reg [31:0] crmd; // ??????
|
||||
reg [31:0] prmd; // ???????
|
||||
reg [31:0] euen; // ??????
|
||||
reg [31:0] ecfg; // ????
|
||||
reg [31:0] estat; // ????
|
||||
reg [31:0] era; // ??????
|
||||
reg [31:0] badv; // ?????
|
||||
reg [31:0] eentry; // ??????
|
||||
reg [31:0] tlbidx; // TLB ??
|
||||
reg [31:0] tlbehi; // TLB ?????
|
||||
reg [31:0] tlbelo0; // TLB ???? 0
|
||||
reg [31:0] tlbelo1; // TLB ???? 1
|
||||
reg [31:0] asid; // ???????
|
||||
reg [31:0] pgdl; // ????????????
|
||||
reg [31:0] pgdh; // ????????????
|
||||
reg [31:0] pgd; // ??????
|
||||
reg [31:0] cpuid; // ?????
|
||||
reg [31:0] save0; // ????0
|
||||
reg [31:0] save1; // ????1
|
||||
reg [31:0] save2; // ????2
|
||||
reg [31:0] save3; // ????3
|
||||
reg [31:0] tid; // ?????
|
||||
reg [31:0] tcfg; // ?????
|
||||
reg [31:0] tval; // ????
|
||||
reg [31:0] ticlr; // ??????
|
||||
reg [31:0] llbctl; // LLbit ??
|
||||
reg [31:0] tlbrentry; // TLB ????????
|
||||
reg [31:0] ctag; // ??????
|
||||
reg [31:0] dmw0; // ????????0
|
||||
reg [31:0] dmw1; // ????????1
|
||||
|
||||
reg [31:0] csr_rdata_r;
|
||||
|
||||
reg timer_en;
|
||||
reg [63:0] timer_64;
|
||||
|
||||
// reg has_int_r;
|
||||
// reg [ 1:0] plv_r;
|
||||
|
||||
wire inst_sc_w;
|
||||
wire inst_csrrd;
|
||||
wire inst_csrwr;
|
||||
wire inst_csrxchg;
|
||||
wire inst_rdcntid_w;
|
||||
wire inst_rdcntvl_w;
|
||||
wire inst_rdcntvh_w;
|
||||
|
||||
wire has_int;
|
||||
|
||||
|
||||
wire excp_ale;
|
||||
wire excp_adef;
|
||||
wire excp_ipe;
|
||||
wire excp_ine;
|
||||
wire inst_break;
|
||||
wire inst_syscall;
|
||||
wire inst_ertn;
|
||||
|
||||
wire [31:0] csr_wdata_temp;
|
||||
|
||||
wire [ 5:0] ecode;
|
||||
wire [ 8:0] esubcode;
|
||||
wire va_error;
|
||||
wire [31:0] bad_va;
|
||||
|
||||
// always @(posedge clk) begin
|
||||
// if(reset) begin
|
||||
// has_int_r <= 0;
|
||||
// plv_r <= 0;
|
||||
// end
|
||||
// else begin
|
||||
// has_int_r <= ((ecfg[`LIE] & estat[`IS]) != 13'b0) & crmd[`IE];
|
||||
// plv_r <= except_en & !inst_ertn ? 2'b0 :
|
||||
// inst_ertn ? prmd[`PPLV] :
|
||||
// csr_we && (csr_addr == `CRMD_ADDR) ? csr_wdata[`PLV] :
|
||||
// crmd[`PLV];
|
||||
// end
|
||||
// end
|
||||
|
||||
// out TODO!
|
||||
assign has_int_out = ((ecfg[`LIE] & estat[`IS]) != 13'b0) & crmd[`IE];
|
||||
assign plv_out = except_en & !inst_ertn ? 2'b0 :
|
||||
inst_ertn ? prmd[`PPLV] :
|
||||
csr_we && (csr_addr == `CRMD_ADDR) ? csr_wdata[`PLV] :
|
||||
crmd[`PLV];
|
||||
|
||||
assign {excp_ale,
|
||||
excp_adef,
|
||||
excp_ipe,
|
||||
excp_ine,
|
||||
inst_break,
|
||||
inst_syscall,
|
||||
inst_ertn,
|
||||
has_int
|
||||
} = csr_vec[7:0];
|
||||
|
||||
assign {ecode, esubcode, va_error, bad_va} = excp_adef ? {`ECODE_ADEF, `ESUBCODE_ADEF, 1'b1, pc } :
|
||||
has_int ? {`ECODE_INT , 9'b0 , 1'b0, 32'b0 } :
|
||||
inst_syscall ? {`ECODE_SYS , 9'b0 , 1'b0, 32'b0 } :
|
||||
inst_break ? {`ECODE_BRK , 9'b0 , 1'b0, 32'b0 } :
|
||||
excp_ine ? {`ECODE_INE , 9'b0 , 1'b0, 32'b0 } :
|
||||
excp_ipe ? {`ECODE_IPE , 9'b0 , 1'b0, 32'b0 } :
|
||||
excp_ale ? {`ECODE_ALE , 9'b0 , 1'b1, error_va} :
|
||||
0;
|
||||
|
||||
assign csr_rdata = csr_rdata_r;
|
||||
|
||||
always @(*) begin
|
||||
if(|csr_op[6:4]) begin
|
||||
case(csr_addr)
|
||||
`CRMD_ADDR : csr_rdata_r <= crmd;
|
||||
`PRMD_ADDR : csr_rdata_r <= prmd;
|
||||
`EUEN_ADDR : csr_rdata_r <= euen;
|
||||
`ECFG_ADDR : csr_rdata_r <= ecfg;
|
||||
`ESTAT_ADDR : csr_rdata_r <= estat;
|
||||
`ERA_ADDR : csr_rdata_r <= era;
|
||||
`BADV_ADDR : csr_rdata_r <= badv;
|
||||
`EENTRY_ADDR : csr_rdata_r <= eentry;
|
||||
`TLBIDX_ADDR : csr_rdata_r <= tlbidx;
|
||||
`TLBEHI_ADDR : csr_rdata_r <= tlbehi;
|
||||
`TLBELO0_ADDR : csr_rdata_r <= tlbelo0;
|
||||
`TLBELO1_ADDR : csr_rdata_r <= tlbelo1;
|
||||
`ASID_ADDR : csr_rdata_r <= asid;
|
||||
`PGDL_ADDR : csr_rdata_r <= pgdl;
|
||||
`PGDH_ADDR : csr_rdata_r <= pgdh;
|
||||
`PGD_ADDR : csr_rdata_r <= pgd;
|
||||
`CPUID_ADDR : csr_rdata_r <= cpuid;
|
||||
`SAVE0_ADDR : csr_rdata_r <= save0;
|
||||
`SAVE1_ADDR : csr_rdata_r <= save1;
|
||||
`SAVE2_ADDR : csr_rdata_r <= save2;
|
||||
`SAVE3_ADDR : csr_rdata_r <= save3;
|
||||
`TID_ADDR : csr_rdata_r <= tid;
|
||||
`TCFG_ADDR : csr_rdata_r <= tcfg;
|
||||
`TVAL_ADDR : csr_rdata_r <= tval;
|
||||
`TICLR_ADDR : csr_rdata_r <= ticlr;
|
||||
`LLBCTL_ADDR : csr_rdata_r <= llbctl;
|
||||
`TLBRENTRY_ADDR : csr_rdata_r <= tlbrentry;
|
||||
`CTAG_ADDR : csr_rdata_r <= ctag;
|
||||
`DMW0_ADDR : csr_rdata_r <= dmw0;
|
||||
`DMW1_ADDR : csr_rdata_r <= dmw1;
|
||||
default : csr_rdata_r <= 32'b0;
|
||||
endcase
|
||||
end
|
||||
else if(|csr_op[3:1]) begin
|
||||
csr_rdata_r <= ({33{csr_op[1]}} & timer_64[31: 0]) |
|
||||
({33{csr_op[2]}} & timer_64[63:32]) |
|
||||
({33{csr_op[3]}} & tid);
|
||||
end
|
||||
else begin
|
||||
//csr_rdata_r <= 32'b0;
|
||||
end
|
||||
end
|
||||
|
||||
assign {inst_csrrd,
|
||||
inst_csrwr,
|
||||
inst_csrxchg,
|
||||
inst_rdcntid_w,
|
||||
inst_rdcntvh_w,
|
||||
inst_rdcntvl_w,
|
||||
inst_sc_w
|
||||
} = csr_op;
|
||||
|
||||
assign csr_wdata_temp = csr_wdata_sel ? (src1 & csr_wdata) | (~src1 & csr_rdata_r) : csr_wdata;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(reset) begin
|
||||
crmd <= 32'd8;
|
||||
prmd <= 0;
|
||||
euen <= 0;
|
||||
ecfg <= 0;
|
||||
estat <= 0;
|
||||
era <= 0;
|
||||
badv <= 0;
|
||||
eentry <= 0;
|
||||
tlbidx <= 0;
|
||||
tlbehi <= 0;
|
||||
tlbelo0 <= 0;
|
||||
tlbelo1 <= 0;
|
||||
asid <= 0;
|
||||
pgdl <= 0;
|
||||
pgdh <= 0;
|
||||
pgd <= 0;
|
||||
cpuid <= 0;
|
||||
save0 <= 0;
|
||||
save1 <= 0;
|
||||
save2 <= 0;
|
||||
save3 <= 0;
|
||||
tid <= 0;
|
||||
tcfg <= 32'hfffffffe;
|
||||
tval <= 0;
|
||||
ticlr <= 0;
|
||||
llbctl <= 0;
|
||||
tlbrentry <= 0;
|
||||
ctag <= 0;
|
||||
dmw0 <= 0;
|
||||
dmw1 <= 0;
|
||||
|
||||
timer_en <= 1'b0;
|
||||
end
|
||||
else if(except_en & ~stallreq_axi) begin
|
||||
if((|csr_vec[7:0] & !inst_ertn) | excp_adef) begin
|
||||
crmd[ `PLV] <= 2'b0;
|
||||
crmd[ `IE] <= 1'b0;
|
||||
|
||||
prmd[`PPLV] <= crmd[`PLV];
|
||||
prmd[ `PIE] <= crmd[`IE ];
|
||||
|
||||
estat[ `ECODE] <= ecode;
|
||||
estat[`ESUBCODE] <= esubcode;
|
||||
|
||||
era <= pc;
|
||||
end
|
||||
else if(inst_ertn) begin
|
||||
crmd[ `PLV] <= prmd[`PPLV];
|
||||
crmd[ `IE] <= prmd[`PIE ];
|
||||
end
|
||||
|
||||
if(va_error) begin
|
||||
badv <= bad_va;
|
||||
end
|
||||
end
|
||||
else if (csr_we) begin
|
||||
case (csr_addr)
|
||||
`CRMD_ADDR : begin
|
||||
crmd[ `PLV] <= csr_wdata_temp[ `PLV];
|
||||
crmd[ `IE] <= csr_wdata_temp[ `IE];
|
||||
crmd[ `DA] <= csr_wdata_temp[ `DA];
|
||||
crmd[ `PG] <= csr_wdata_temp[ `PG];
|
||||
crmd[`DATF] <= csr_wdata_temp[`DATF];
|
||||
crmd[`DATM] <= csr_wdata_temp[`DATM];
|
||||
end
|
||||
`PRMD_ADDR : begin
|
||||
prmd[`PPLV] <= csr_wdata_temp[`PPLV];
|
||||
prmd[ `PIE] <= csr_wdata_temp[ `PIE];
|
||||
end
|
||||
`EUEN_ADDR : euen <= csr_wdata_temp;
|
||||
`ECFG_ADDR : begin
|
||||
ecfg <= csr_wdata_temp; // ????????????????
|
||||
|
||||
end
|
||||
`ESTAT_ADDR : estat[1:0] <= csr_wdata_temp[1:0];
|
||||
`ERA_ADDR : era <= csr_wdata_temp;
|
||||
`BADV_ADDR : badv <= csr_wdata_temp; // MORE
|
||||
`EENTRY_ADDR : eentry[31:6] <= csr_wdata_temp[31:6];
|
||||
`TLBIDX_ADDR : tlbidx <= csr_wdata_temp; // PASS
|
||||
`TLBEHI_ADDR : tlbehi <= csr_wdata_temp; // PASS
|
||||
`TLBELO0_ADDR : tlbelo0 <= csr_wdata_temp; // PASS
|
||||
`TLBELO1_ADDR : tlbelo1 <= csr_wdata_temp; // PASS
|
||||
`ASID_ADDR : asid[`TLB_ASID] <= csr_wdata_temp[`TLB_ASID]; // MORE
|
||||
`PGDL_ADDR : pgdl <= csr_wdata_temp;
|
||||
`PGDH_ADDR : pgdh <= csr_wdata_temp;
|
||||
`PGD_ADDR : pgd <= csr_wdata_temp;
|
||||
//`CPUID_ADDR : cpuid <= csr_wdata_temp;
|
||||
`SAVE0_ADDR : save0 <= csr_wdata_temp;
|
||||
`SAVE1_ADDR : save1 <= csr_wdata_temp;
|
||||
`SAVE2_ADDR : save2 <= csr_wdata_temp;
|
||||
`SAVE3_ADDR : save3 <= csr_wdata_temp;
|
||||
`TID_ADDR : tid <= csr_wdata_temp;
|
||||
`TCFG_ADDR : begin
|
||||
tcfg[ `EN] <= csr_wdata_temp[ `EN];
|
||||
tcfg[`PERIODIC] <= csr_wdata_temp[`PERIODIC];
|
||||
tcfg[ `INITVAL] <= csr_wdata_temp[ `INITVAL];
|
||||
|
||||
tval <= {csr_wdata_temp[ `INITVAL], 2'b0};
|
||||
timer_en <= csr_wdata_temp[`EN];
|
||||
end
|
||||
//`TVAL_ADDR : tval <= {csr_wdata_temp[ `INITVAL], 2'b0};
|
||||
`TICLR_ADDR : begin
|
||||
if(csr_wdata_temp[`CLR]) begin
|
||||
estat[11] <= 1'b0;
|
||||
end
|
||||
end
|
||||
`LLBCTL_ADDR : llbctl <= csr_wdata_temp; // PASS
|
||||
`TLBRENTRY_ADDR : tlbrentry <= csr_wdata_temp; // PASS
|
||||
`CTAG_ADDR : ctag <= csr_wdata_temp;
|
||||
`DMW0_ADDR : begin
|
||||
dmw0[`PLV0] <= csr_wdata_temp[`PLV0];
|
||||
dmw0[`PLV3] <= csr_wdata_temp[`PLV3];
|
||||
dmw0[`DMW_MAT] <= csr_wdata_temp[`DMW_MAT];
|
||||
dmw0[`PSEG] <= csr_wdata_temp[`PSEG];
|
||||
dmw0[`VSEG] <= csr_wdata_temp[`VSEG];
|
||||
end
|
||||
`DMW1_ADDR : begin
|
||||
dmw1[`PLV0] <= csr_wdata_temp[`PLV0];
|
||||
dmw1[`PLV3] <= csr_wdata_temp[`PLV3];
|
||||
dmw1[`DMW_MAT] <= csr_wdata_temp[`DMW_MAT];
|
||||
dmw1[`PSEG] <= csr_wdata_temp[`PSEG];
|
||||
dmw1[`VSEG] <= csr_wdata_temp[`VSEG];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
else begin
|
||||
// estat
|
||||
if(timer_en && (tval == 32'b0)) begin
|
||||
estat[11] <= 1'b1;
|
||||
timer_en <= tcfg[`PERIODIC];
|
||||
end
|
||||
//estat[9:0] <= intrpt; // ???
|
||||
|
||||
// tval
|
||||
if(timer_en) begin
|
||||
if (tval != 32'b0) begin
|
||||
tval <= tval - 32'b1;
|
||||
end
|
||||
else if (tval == 32'b0) begin
|
||||
tval <= tcfg[`PERIODIC] ? {tcfg[`INITVAL], 2'b0} : 32'hffffffff;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign except_en = |csr_vec[7:0];
|
||||
assign new_pc = (|csr_vec[7:0] & !inst_ertn) | excp_adef ? eentry :
|
||||
inst_ertn ? era :
|
||||
32'b0; // TODO!
|
||||
|
||||
|
||||
|
||||
//timer_64
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
timer_64 <= 64'b0;
|
||||
end
|
||||
else begin
|
||||
timer_64 <= timer_64 + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
65
lacpu/rtl/mycpu/dcache.v
Normal file
65
lacpu/rtl/mycpu/dcache.v
Normal 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
|
||||
52
lacpu/rtl/mycpu/div.v
Normal file
52
lacpu/rtl/mycpu/div.v
Normal file
@@ -0,0 +1,52 @@
|
||||
module div(
|
||||
input clk,
|
||||
input reset,
|
||||
output stallreq,
|
||||
input in_valid,
|
||||
output out_valid,
|
||||
|
||||
input [31:0] a,
|
||||
input [31:0] b,
|
||||
|
||||
output reg [31:0] quotient, //商
|
||||
output reg [31:0] remainder //余数
|
||||
);
|
||||
|
||||
reg [ 5:0] cnt;
|
||||
wire [31:0] sub_result;
|
||||
wire carry;
|
||||
wire [31:0] temp;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
cnt <= 0;
|
||||
end
|
||||
else if (cnt != 0) begin
|
||||
cnt <= cnt -1;
|
||||
end
|
||||
else if (in_valid) begin
|
||||
cnt <= 32;
|
||||
end
|
||||
end
|
||||
|
||||
assign temp = {remainder[30:0],quotient[31]};
|
||||
assign carry = temp < b ? 0 : 1;
|
||||
assign sub_result = carry ? temp - b : temp;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
quotient <= 0;
|
||||
remainder <= 0;
|
||||
end
|
||||
else if (cnt != 0) begin
|
||||
{remainder, quotient} <= {sub_result, quotient[30:0], carry};
|
||||
end
|
||||
else if (in_valid) begin
|
||||
quotient <= a;
|
||||
remainder <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
assign out_valid = (cnt==0);
|
||||
assign stallreq = in_valid | (~(cnt==0));
|
||||
endmodule
|
||||
253
lacpu/rtl/mycpu/exe_stage.v
Normal file
253
lacpu/rtl/mycpu/exe_stage.v
Normal file
@@ -0,0 +1,253 @@
|
||||
module exe_stage
|
||||
#(
|
||||
parameter BR_BUS_WD = 33,
|
||||
parameter DS_TO_ES_BUS_WD = 301,
|
||||
parameter ES_TO_MS_BUS_WD = 271,
|
||||
parameter MS_TO_ES_BUS_WD = 38,
|
||||
parameter WS_TO_ES_BUS_WD = 38
|
||||
)
|
||||
(
|
||||
input clk,
|
||||
input reset,
|
||||
input flush,
|
||||
input [ 5:0] stall,
|
||||
|
||||
output stallreq_es,
|
||||
|
||||
input [DS_TO_ES_BUS_WD -1:0] ds_to_es_bus,
|
||||
output [ES_TO_MS_BUS_WD -1:0] es_to_ms_bus,
|
||||
input [MS_TO_ES_BUS_WD -1:0] ms_to_es_bus,
|
||||
input [WS_TO_ES_BUS_WD -1:0] ws_to_es_bus,
|
||||
|
||||
output [BR_BUS_WD -1:0] br_bus,
|
||||
|
||||
output data_sram_en,
|
||||
output [ 3:0] data_sram_we,
|
||||
output [31:0] data_sram_addr,
|
||||
output [31:0] data_sram_wdata
|
||||
);
|
||||
|
||||
reg [DS_TO_ES_BUS_WD -1:0] ds_to_es_bus_r;
|
||||
|
||||
wire [63:0] csr_vec;
|
||||
wire [63:0] csr_vec_temp;
|
||||
wire [ 6:0] csr_op;
|
||||
wire csr_wdata_sel;
|
||||
wire [13:0] csr_addr;
|
||||
wire csr_we;
|
||||
wire [11:0] alu_op;
|
||||
wire [ 3:0] mul_div_op;
|
||||
wire mul_div_sign;
|
||||
wire [ 8:0] branch_op;
|
||||
wire [ 2:0] store_op;
|
||||
wire [ 5:0] load_op;
|
||||
wire reg_we;
|
||||
wire src1_is_pc;
|
||||
wire src2_is_imm;
|
||||
wire src2_is_4;
|
||||
wire [ 4:0] rj;
|
||||
wire [ 4:0] rkd;
|
||||
wire [31:0] rj_value;
|
||||
wire [31:0] rkd_value;
|
||||
wire [ 4:0] dest;
|
||||
wire [31:0] imm;
|
||||
wire [31:0] es_pc;
|
||||
wire [31:0] inst;
|
||||
|
||||
wire ms_reg_we;
|
||||
wire [ 4:0] ms_dest;
|
||||
wire [31:0] ms_result;
|
||||
wire ws_reg_we;
|
||||
wire [ 4:0] ws_dest;
|
||||
wire [31:0] ws_result;
|
||||
|
||||
wire [31:0] src1;
|
||||
wire [31:0] src2;
|
||||
wire [31:0] alu_src1;
|
||||
wire [31:0] alu_src2;
|
||||
wire [31:0] alu_result;
|
||||
|
||||
wire br_taken;
|
||||
wire [31:0] br_target;
|
||||
wire br_flush;
|
||||
|
||||
wire data_sram_en_temp;
|
||||
wire [ 3:0] data_sram_we_temp;
|
||||
|
||||
wire stallreq_for_mul_div;
|
||||
wire [31:0] mul_div_result;
|
||||
wire [31:0] es_result;
|
||||
|
||||
wire [31:0] csr_wdata;
|
||||
wire [63:0] csr_bus;
|
||||
|
||||
wire excp_ale;
|
||||
|
||||
assign {csr_vec_temp ,//300:237
|
||||
csr_op ,//236:230
|
||||
csr_wdata_sel ,//229:229
|
||||
csr_addr ,//228:215
|
||||
csr_we ,//214:214
|
||||
alu_op ,//213:202
|
||||
mul_div_op ,//198:189
|
||||
mul_div_sign ,//197:197
|
||||
branch_op ,//196:188
|
||||
store_op ,//187:185
|
||||
load_op ,//184:179
|
||||
reg_we ,//178:178
|
||||
src1_is_pc ,//177:177
|
||||
src2_is_imm ,//176:176
|
||||
src2_is_4 ,//175:175
|
||||
rj ,//174:170
|
||||
rkd ,//169:165
|
||||
rj_value ,//164:133
|
||||
rkd_value ,//132:101
|
||||
dest ,//100:96
|
||||
imm ,//95 :64
|
||||
es_pc ,//63 :32
|
||||
inst //31 :0
|
||||
} = ds_to_es_bus_r;
|
||||
|
||||
assign {ms_reg_we,
|
||||
ms_dest,
|
||||
ms_result
|
||||
} = ms_to_es_bus;
|
||||
|
||||
assign {ws_reg_we,
|
||||
ws_dest,
|
||||
ws_result
|
||||
} = ws_to_es_bus;
|
||||
|
||||
assign es_to_ms_bus = {csr_vec ,//270:207
|
||||
csr_bus ,//206:143
|
||||
load_op ,//142:137
|
||||
store_op ,//136:134
|
||||
reg_we ,//133:133
|
||||
dest ,//132:128
|
||||
es_result,//127:96
|
||||
src1 ,//95 :64
|
||||
es_pc ,//63 :32
|
||||
inst //31 :0
|
||||
};
|
||||
|
||||
assign br_flush = br_taken;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
ds_to_es_bus_r <= 0;
|
||||
end
|
||||
else if (flush) begin
|
||||
ds_to_es_bus_r <= 0;
|
||||
end
|
||||
//nop, id stall and ex not stall
|
||||
else if (stall[2]&(!stall[3])) begin
|
||||
ds_to_es_bus_r <= 0;
|
||||
end
|
||||
//nop, id not stall and br_bus[32]
|
||||
else if (!stall[2]&br_flush) begin
|
||||
ds_to_es_bus_r <= 0;
|
||||
end
|
||||
// id not stall so can go on
|
||||
else if (!stall[2]) begin
|
||||
ds_to_es_bus_r <= ds_to_es_bus;
|
||||
end
|
||||
end
|
||||
|
||||
assign src1 = ms_reg_we & (ms_dest == rj ) & (rj != 1'b0) ? ms_result :
|
||||
ws_reg_we & (ws_dest == rj ) & (rj != 1'b0) ? ws_result :
|
||||
rj_value;
|
||||
assign src2 = ms_reg_we & (ms_dest == rkd) & (rkd != 1'b0) ? ms_result :
|
||||
ws_reg_we & (ws_dest == rkd) & (rkd != 1'b0) ? ws_result :
|
||||
rkd_value;
|
||||
|
||||
assign alu_src1 = src1_is_pc ? es_pc :
|
||||
src1;
|
||||
assign alu_src2 = src2_is_4 ? 3'd4 :
|
||||
src2_is_imm ? imm :
|
||||
src2;
|
||||
|
||||
alu u_alu(
|
||||
.alu_op (alu_op ),
|
||||
.alu_src1 (alu_src1 ),
|
||||
.alu_src2 (alu_src2 ),
|
||||
.alu_result(alu_result)
|
||||
);
|
||||
|
||||
bru u_bru(
|
||||
.pc (es_pc ),
|
||||
.rj_value (src1 ),
|
||||
.rkd_value(src2 ),
|
||||
.imm (imm ),
|
||||
.branch_op(branch_op),
|
||||
.br_taken (br_taken ),
|
||||
.br_target(br_target)
|
||||
);
|
||||
|
||||
wire csr_cancel;
|
||||
reg csr_cancel_reg;
|
||||
|
||||
assign csr_cancel = flush ? 1'b0 : |csr_vec[31:0];// TODO!
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
csr_cancel_reg <= 0;
|
||||
end
|
||||
else if (flush) begin
|
||||
csr_cancel_reg <= 0;
|
||||
end
|
||||
else if (csr_cancel) begin
|
||||
csr_cancel_reg <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
assign br_bus = {br_taken & ~(csr_cancel|csr_cancel_reg),
|
||||
br_target
|
||||
};
|
||||
|
||||
lsu u_lsu(
|
||||
.load_op (load_op ),
|
||||
.store_op (store_op ),
|
||||
.rj_value (src1 ),
|
||||
.rkd_value (src2 ),
|
||||
.imm (imm ),
|
||||
|
||||
.excp_ale (excp_ale ),
|
||||
|
||||
.data_sram_en (data_sram_en_temp),
|
||||
.data_sram_we (data_sram_we_temp),
|
||||
.data_sram_addr (data_sram_addr ),
|
||||
.data_sram_wdata(data_sram_wdata )
|
||||
);
|
||||
assign data_sram_en = (csr_cancel|csr_cancel_reg) ? 1'b0 : data_sram_en_temp;
|
||||
assign data_sram_we = {4{data_sram_en}} & data_sram_we_temp;
|
||||
|
||||
// mul_div
|
||||
mul_div_top u_mul_div_top(
|
||||
.clk (clk ),
|
||||
.reset (reset | flush ),
|
||||
.stall (stall ),
|
||||
.stallreq (stallreq_for_mul_div),
|
||||
.mul_div_op (mul_div_op ),
|
||||
.mul_div_sign (mul_div_sign ),
|
||||
.a (alu_src1 ),
|
||||
.b (alu_src2 ),
|
||||
.mul_div_result(mul_div_result )
|
||||
);
|
||||
|
||||
assign es_result = (|mul_div_op ) ? mul_div_result :
|
||||
(|load_op | |store_op) ? data_sram_addr :
|
||||
alu_result;
|
||||
|
||||
assign csr_wdata = src2;
|
||||
assign csr_bus = {csr_we,
|
||||
csr_wdata_sel,
|
||||
csr_op,
|
||||
csr_addr,
|
||||
csr_wdata
|
||||
};
|
||||
|
||||
assign csr_vec = {csr_vec_temp[63:8], excp_ale, csr_vec_temp[6:0]};
|
||||
|
||||
assign stallreq_es = stallreq_for_mul_div;
|
||||
|
||||
endmodule
|
||||
63
lacpu/rtl/mycpu/icache.v
Normal file
63
lacpu/rtl/mycpu/icache.v
Normal 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
|
||||
257
lacpu/rtl/mycpu/id_stage.v
Normal file
257
lacpu/rtl/mycpu/id_stage.v
Normal file
@@ -0,0 +1,257 @@
|
||||
module id_stage
|
||||
#(
|
||||
parameter FS_TO_DS_BUS_WD = 65,
|
||||
parameter DS_TO_ES_BUS_WD = 301,
|
||||
parameter WS_TO_RF_BUS_WD = 38
|
||||
)
|
||||
(
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input flush,
|
||||
input [ 5:0] stall,
|
||||
input br_taken,
|
||||
|
||||
output stallreq_ds,
|
||||
|
||||
input pc_valid,
|
||||
input [31:0] inst_sram_rdata,
|
||||
input [ 1:0] csr_plv,
|
||||
input csr_has_int,
|
||||
|
||||
input [FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus,
|
||||
input [WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus,
|
||||
output [DS_TO_ES_BUS_WD -1:0] ds_to_es_bus
|
||||
);
|
||||
reg [FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus_r;
|
||||
reg pc_valid_r;
|
||||
|
||||
reg [31:0] inst_r;
|
||||
reg stall_flag;
|
||||
|
||||
reg [ 6:0] ex_load_buffer;
|
||||
reg ex_csr_buffer;
|
||||
|
||||
wire br_flush;
|
||||
wire [31:0] ds_pc;
|
||||
|
||||
wire src1_is_pc;
|
||||
wire src2_is_imm;
|
||||
wire src2_is_4;
|
||||
wire src_reg_is_rd;
|
||||
wire [ 4:0] rj;
|
||||
wire [ 4:0] rk;
|
||||
wire [ 4:0] rd;
|
||||
wire [ 4:0] rkd;
|
||||
wire [31:0] imm;
|
||||
wire [ 4:0] dest;
|
||||
wire [11:0] alu_op;
|
||||
wire [ 3:0] mul_div_op;
|
||||
wire mul_div_sign;
|
||||
wire [ 8:0] branch_op;
|
||||
wire [ 5:0] load_op;
|
||||
wire [ 2:0] store_op;
|
||||
wire reg_we;
|
||||
|
||||
wire csr_we;
|
||||
wire [ 6:0] csr_op;
|
||||
wire [13:0] csr_addr;
|
||||
wire csr_wdata_sel;
|
||||
|
||||
wire [31:0] inst;
|
||||
wire [31:0] next_inst;
|
||||
|
||||
wire [ 4:0] rf_raddr1;
|
||||
wire [31:0] rf_rdata1;
|
||||
wire [ 4:0] rf_raddr2;
|
||||
wire [31:0] rf_rdata2;
|
||||
wire rf_we;
|
||||
wire [ 4:0] rf_waddr;
|
||||
wire [31:0] rf_wdata;
|
||||
|
||||
wire [31:0] rj_value;
|
||||
wire [31:0] rkd_value;
|
||||
|
||||
wire [ 4:0] ex_rf_waddr;
|
||||
wire ex_is_load;
|
||||
wire ex_is_csr;
|
||||
wire ex_rf_we;
|
||||
wire stallreq_load;
|
||||
wire stallreq_csr;
|
||||
|
||||
wire excp_adef;
|
||||
wire [31:0] csr_vec_h;
|
||||
wire [31:0] csr_vec_l;
|
||||
wire [63:0] csr_vec;
|
||||
|
||||
assign {csr_vec_h,
|
||||
excp_adef,
|
||||
ds_pc
|
||||
} = fs_to_ds_bus_r;
|
||||
|
||||
assign csr_vec = {csr_vec_h, csr_vec_l};
|
||||
|
||||
assign br_flush = br_taken;
|
||||
|
||||
assign {rf_we , //37:37
|
||||
rf_waddr, //36:32
|
||||
rf_wdata //31:0
|
||||
} = ws_to_rf_bus;
|
||||
|
||||
|
||||
|
||||
assign ds_to_es_bus = {csr_vec & {64{pc_valid_r}} ,//300:237
|
||||
csr_op ,//236:230
|
||||
csr_wdata_sel ,//229:229
|
||||
csr_addr ,//228:215
|
||||
csr_we ,//214:214
|
||||
alu_op ,//213:202
|
||||
mul_div_op & {4{pc_valid_r}} ,//198:189
|
||||
mul_div_sign & pc_valid_r ,//197:197
|
||||
branch_op & {9{pc_valid_r}} ,//196:188
|
||||
store_op & {3{pc_valid_r}} ,//187:185
|
||||
load_op & {6{pc_valid_r}} ,//184:179
|
||||
reg_we & pc_valid_r ,//178:178
|
||||
src1_is_pc ,//177:177
|
||||
src2_is_imm ,//176:176
|
||||
src2_is_4 ,//175:175
|
||||
rj ,//174:170
|
||||
rkd ,//169:165
|
||||
rj_value ,//164:133
|
||||
rkd_value ,//132:101
|
||||
dest ,//100:96
|
||||
imm ,//95 :64
|
||||
ds_pc ,//63 :32
|
||||
inst & {32{pc_valid_r}} //31 :0
|
||||
};
|
||||
|
||||
always @ (posedge clk)begin
|
||||
if (reset) begin
|
||||
pc_valid_r <= 1'b0;
|
||||
fs_to_ds_bus_r <= 0;
|
||||
end
|
||||
else if (flush) begin
|
||||
pc_valid_r <= 1'b0;
|
||||
fs_to_ds_bus_r <= 0;
|
||||
end
|
||||
//nop, ID stall and EX not stall
|
||||
else if (stall[1] & (!stall[2]))begin
|
||||
pc_valid_r <= 1'b0;
|
||||
fs_to_ds_bus_r <= 0;
|
||||
end
|
||||
//nop, ID not stall but branch
|
||||
else if (!stall[1] & br_flush) begin
|
||||
pc_valid_r <= 1'b0;
|
||||
fs_to_ds_bus_r <= 0;
|
||||
end
|
||||
// ID not stall so go on
|
||||
else if (!stall[1]) begin
|
||||
pc_valid_r <= pc_valid;
|
||||
fs_to_ds_bus_r <= fs_to_ds_bus;
|
||||
end
|
||||
end
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
inst_r <= 64'b0;
|
||||
stall_flag <= 1'b0;
|
||||
end
|
||||
else if (flush) begin
|
||||
inst_r <= 64'b0;
|
||||
stall_flag <= 1'b0;
|
||||
end
|
||||
//if not stall, get inst from inst_sram
|
||||
else if (!stall[1]) begin
|
||||
inst_r <= inst_sram_rdata;
|
||||
stall_flag <= 1'b0;
|
||||
end
|
||||
else if (stall_flag) begin
|
||||
|
||||
end
|
||||
//if stall and id stall, get inst from inst_ram ?
|
||||
else if (stall[1]&stall[2]) begin
|
||||
inst_r <= inst_sram_rdata;
|
||||
stall_flag <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
assign next_inst = stall_flag ? inst_r : inst_sram_rdata;
|
||||
assign inst = ~pc_valid_r ? 32'b0 : next_inst;
|
||||
|
||||
inst_decoder u_inst_decoder(
|
||||
.inst (inst ),
|
||||
.src1_is_pc (src1_is_pc ),
|
||||
.src2_is_imm (src2_is_imm ),
|
||||
.src2_is_4 (src2_is_4 ),
|
||||
.src_reg_is_rd (src_reg_is_rd ),
|
||||
.rj (rj ),
|
||||
.rk (rk ),
|
||||
.rd (rd ),
|
||||
.imm (imm ),
|
||||
.dest (dest ),
|
||||
.alu_op (alu_op ),
|
||||
.mul_div_op (mul_div_op ),
|
||||
.mul_div_sign (mul_div_sign ),
|
||||
.branch_op (branch_op ),
|
||||
.load_op (load_op ),
|
||||
.store_op (store_op ),
|
||||
.excp_adef (excp_adef ),
|
||||
.csr_plv (csr_plv ),
|
||||
.csr_has_int (csr_has_int ),
|
||||
.csr_we (csr_we ),
|
||||
.csr_op (csr_op ),
|
||||
.csr_addr (csr_addr ),
|
||||
.csr_wdata_sel (csr_wdata_sel ),
|
||||
.csr_vec_l (csr_vec_l ),
|
||||
.reg_we (reg_we )
|
||||
);
|
||||
|
||||
assign rf_raddr1 = rj;
|
||||
assign rf_raddr2 = src_reg_is_rd ? rd : rk;
|
||||
assign rkd = src_reg_is_rd ? rd : rk;
|
||||
|
||||
regfile u_regfile(
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.raddr1 (rf_raddr1),
|
||||
.rdata1 (rf_rdata1),
|
||||
.raddr2 (rf_raddr2),
|
||||
.rdata2 (rf_rdata2),
|
||||
.we (rf_we ),
|
||||
.waddr (rf_waddr ),
|
||||
.wdata (rf_wdata )
|
||||
);
|
||||
|
||||
assign rj_value = rf_rdata1;
|
||||
assign rkd_value = rf_rdata2;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
ex_load_buffer <= 7'b0;
|
||||
ex_csr_buffer <= 1'b0;
|
||||
end
|
||||
else if (flush) begin
|
||||
ex_load_buffer <= 7'b0;
|
||||
ex_csr_buffer <= 1'b0;
|
||||
end
|
||||
else if (stall[2]&(!stall[3])) begin
|
||||
ex_load_buffer <= 7'b0;
|
||||
ex_csr_buffer <= 1'b0;
|
||||
end
|
||||
else if (!stall[2]) begin
|
||||
ex_load_buffer <= {|load_op, rf_we, rf_waddr};
|
||||
ex_csr_buffer <= |csr_op;
|
||||
end
|
||||
end
|
||||
|
||||
assign {ex_is_load,
|
||||
ex_rf_we,
|
||||
ex_rf_waddr
|
||||
} = ex_load_buffer;
|
||||
assign ex_is_csr = ex_csr_buffer;
|
||||
//ex段为load指令,且发生数据相关时,id段需要被暂停
|
||||
assign stallreq_load = ex_is_load & ex_rf_we & ((ex_rf_waddr==rj_value & rj_value!=0)|(ex_rf_waddr==rkd_value & rkd_value!=0));
|
||||
assign stallreq_csr = ex_is_csr & ex_rf_we & ((ex_rf_waddr==rj_value & rj_value!=0)|(ex_rf_waddr==rkd_value & rkd_value!=0));
|
||||
assign stallreq_ds = stallreq_load | stallreq_csr;
|
||||
|
||||
endmodule
|
||||
76
lacpu/rtl/mycpu/if_stage.v
Normal file
76
lacpu/rtl/mycpu/if_stage.v
Normal file
@@ -0,0 +1,76 @@
|
||||
module if_stage
|
||||
#(
|
||||
parameter BR_BUS_WD = 33,
|
||||
parameter FS_TO_DS_BUS_WD = 65
|
||||
)
|
||||
(
|
||||
input clk ,
|
||||
input reset,
|
||||
|
||||
input flush,
|
||||
input [ 5:0] stall,
|
||||
|
||||
input [31:0] new_pc,
|
||||
|
||||
input timer_int,
|
||||
|
||||
output inst_sram_en ,
|
||||
output [ 3:0] inst_sram_we ,
|
||||
output [31:0] inst_sram_addr ,
|
||||
output [31:0] inst_sram_wdata,
|
||||
|
||||
input [BR_BUS_WD -1:0] br_bus,
|
||||
output [FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus
|
||||
);
|
||||
reg pc_valid;
|
||||
reg [31:0] fs_pc;
|
||||
|
||||
reg excp_adef;
|
||||
reg [31:0] csr_vec_h;
|
||||
|
||||
wire [31:0] seq_pc;
|
||||
wire [31:0] next_pc;
|
||||
|
||||
wire br_taken;
|
||||
wire [31:0] br_target;
|
||||
|
||||
|
||||
assign fs_to_ds_bus = {csr_vec_h, //64:33
|
||||
excp_adef, //32:32
|
||||
fs_pc //31:0
|
||||
};
|
||||
|
||||
assign {br_taken,
|
||||
br_target
|
||||
} = br_bus;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
pc_valid <= 1'b0;
|
||||
fs_pc <= 32'h1bff_fffc;
|
||||
excp_adef <= 1'b0;
|
||||
csr_vec_h <= 32'b0;
|
||||
end
|
||||
else if (flush) begin
|
||||
pc_valid <= 1'b1;
|
||||
fs_pc <= new_pc;
|
||||
excp_adef <= |new_pc[1:0];
|
||||
csr_vec_h <= 32'b0;
|
||||
end
|
||||
else if (!stall[0]) begin
|
||||
pc_valid <= 1'b1;
|
||||
fs_pc <= next_pc;
|
||||
excp_adef <= |next_pc[1:0];
|
||||
csr_vec_h <= 0; // timer_int; TODO!
|
||||
end
|
||||
end
|
||||
|
||||
assign seq_pc = fs_pc + 3'h4;
|
||||
assign next_pc = br_taken ? br_target : seq_pc;
|
||||
|
||||
|
||||
assign inst_sram_en = flush | (br_taken ? 1'b0 : pc_valid);
|
||||
assign inst_sram_we = 4'h0;
|
||||
assign inst_sram_addr = fs_pc;
|
||||
assign inst_sram_wdata = 32'b0;
|
||||
endmodule
|
||||
545
lacpu/rtl/mycpu/inst_decoder.v
Normal file
545
lacpu/rtl/mycpu/inst_decoder.v
Normal file
@@ -0,0 +1,545 @@
|
||||
module inst_decoder(
|
||||
input [31:0] inst,
|
||||
|
||||
output src1_is_pc,
|
||||
output src2_is_imm,
|
||||
output src2_is_4,
|
||||
output src_reg_is_rd,
|
||||
output [ 4:0] rj,
|
||||
output [ 4:0] rk,
|
||||
output [ 4:0] rd,
|
||||
output [31:0] imm,
|
||||
output [ 4:0] dest,
|
||||
|
||||
// alu
|
||||
output [11:0] alu_op,
|
||||
|
||||
// mul div
|
||||
output [ 3:0] mul_div_op,
|
||||
output mul_div_sign,
|
||||
|
||||
// branch
|
||||
output [ 8:0] branch_op,
|
||||
output [ 5:0] load_op,
|
||||
output [ 2:0] store_op,
|
||||
|
||||
// csr
|
||||
input excp_adef,
|
||||
input [ 1:0] csr_plv,
|
||||
input csr_has_int,
|
||||
|
||||
output csr_we,
|
||||
output [ 6:0] csr_op,
|
||||
output [13:0] csr_addr,
|
||||
output csr_wdata_sel,
|
||||
output [31:0] csr_vec_l,
|
||||
|
||||
//output [ 3:0] sel_rf_res,
|
||||
|
||||
output reg_we
|
||||
);
|
||||
wire dest_is_r1;
|
||||
wire dest_is_rj;
|
||||
|
||||
wire [ 5:0] op_31_26;
|
||||
wire [ 3:0] op_25_22;
|
||||
wire [ 1:0] op_21_20;
|
||||
wire [ 4:0] op_19_15;
|
||||
wire [63:0] op_31_26_d;
|
||||
wire [15:0] op_25_22_d;
|
||||
wire [ 3:0] op_21_20_d;
|
||||
wire [31:0] op_19_15_d;
|
||||
wire [31:0] rd_d;
|
||||
wire [31:0] rj_d;
|
||||
wire [31:0] rk_d;
|
||||
wire [11:0] i12;
|
||||
wire [13:0] i14;
|
||||
wire [19:0] i20;
|
||||
wire [15:0] i16;
|
||||
wire [25:0] i26;
|
||||
wire [13:0] csr_idx;
|
||||
|
||||
wire inst_add_w;
|
||||
wire inst_sub_w;
|
||||
wire inst_slt;
|
||||
wire inst_sltu;
|
||||
wire inst_nor;
|
||||
wire inst_and;
|
||||
wire inst_or;
|
||||
wire inst_xor;
|
||||
wire inst_lu12i_w;
|
||||
wire inst_addi_w;
|
||||
wire inst_slti;
|
||||
wire inst_sltui;
|
||||
wire inst_pcaddi;
|
||||
wire inst_pcaddu12i;
|
||||
//wire inst_andn;
|
||||
//wire inst_orn;
|
||||
wire inst_andi;
|
||||
wire inst_ori;
|
||||
wire inst_xori;
|
||||
wire inst_mul_w;
|
||||
wire inst_mulh_w;
|
||||
wire inst_mulh_wu;
|
||||
wire inst_div_w;
|
||||
wire inst_mod_w;
|
||||
wire inst_div_wu;
|
||||
wire inst_mod_wu;
|
||||
|
||||
wire inst_slli_w;
|
||||
wire inst_srli_w;
|
||||
wire inst_srai_w;
|
||||
wire inst_sll_w;
|
||||
wire inst_srl_w;
|
||||
wire inst_sra_w;
|
||||
|
||||
wire inst_jirl;
|
||||
wire inst_b;
|
||||
wire inst_bl;
|
||||
wire inst_beq;
|
||||
wire inst_bne;
|
||||
wire inst_blt;
|
||||
wire inst_bge;
|
||||
wire inst_bltu;
|
||||
wire inst_bgeu;
|
||||
|
||||
wire inst_ll_w;
|
||||
wire inst_sc_w;
|
||||
wire inst_ld_b;
|
||||
wire inst_ld_bu;
|
||||
wire inst_ld_h;
|
||||
wire inst_ld_hu;
|
||||
wire inst_ld_w;
|
||||
wire inst_st_b;
|
||||
wire inst_st_h;
|
||||
wire inst_st_w;
|
||||
|
||||
wire inst_syscall;
|
||||
wire inst_break;
|
||||
wire inst_csrrd;
|
||||
wire inst_csrwr;
|
||||
wire inst_csrxchg;
|
||||
wire inst_ertn;
|
||||
|
||||
wire inst_rdcntid_w;
|
||||
wire inst_rdcntvl_w;
|
||||
wire inst_rdcntvh_w;
|
||||
//wire inst_idle;
|
||||
|
||||
//wire inst_tlbsrch;
|
||||
//wire inst_tlbrd;
|
||||
//wire inst_tlbwr;
|
||||
//wire inst_tlbfill;
|
||||
//wire inst_invtlb;
|
||||
|
||||
//wire inst_cacop;
|
||||
//wire inst_preld;
|
||||
wire inst_dbar;
|
||||
wire inst_ibar;
|
||||
|
||||
wire need_ui5;
|
||||
wire need_si12;
|
||||
wire need_ui12;
|
||||
wire need_si14_pc;
|
||||
wire need_si16_pc;
|
||||
wire need_si20;
|
||||
wire need_si20_pc;
|
||||
wire need_si26_pc;
|
||||
|
||||
wire inst_valid;
|
||||
wire excp_ine;
|
||||
|
||||
wire kernel_inst;
|
||||
wire excp_ipe;
|
||||
|
||||
|
||||
assign op_31_26 = inst[31:26];
|
||||
assign op_25_22 = inst[25:22];
|
||||
assign op_21_20 = inst[21:20];
|
||||
assign op_19_15 = inst[19:15];
|
||||
|
||||
assign rd = inst[ 4: 0];
|
||||
assign rj = inst[ 9: 5];
|
||||
assign rk = inst[14:10];
|
||||
|
||||
assign i12 = inst[21:10];
|
||||
assign i14 = inst[23:10];
|
||||
assign i20 = inst[24: 5];
|
||||
assign i16 = inst[25:10];
|
||||
assign i26 = {inst[ 9: 0], inst[25:10]};
|
||||
|
||||
assign csr_idx = inst[23:10];
|
||||
|
||||
decoder_6_64 u_dec0(.in(op_31_26 ), .out(op_31_26_d ));
|
||||
decoder_4_16 u_dec1(.in(op_25_22 ), .out(op_25_22_d ));
|
||||
decoder_2_4 u_dec2(.in(op_21_20 ), .out(op_21_20_d ));
|
||||
decoder_5_32 u_dec3(.in(op_19_15 ), .out(op_19_15_d ));
|
||||
|
||||
decoder_5_32 u_dec4(.in(rd ), .out(rd_d ));
|
||||
decoder_5_32 u_dec5(.in(rj ), .out(rj_d ));
|
||||
decoder_5_32 u_dec6(.in(rk ), .out(rk_d ));
|
||||
|
||||
assign inst_add_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h00];
|
||||
assign inst_sub_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h02];
|
||||
assign inst_slt = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h04];
|
||||
assign inst_sltu = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h05];
|
||||
assign inst_nor = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h08];
|
||||
assign inst_and = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h09];
|
||||
assign inst_or = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0a];
|
||||
assign inst_xor = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0b];
|
||||
//assign inst_orn = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0c];
|
||||
//assign inst_andn = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0d];
|
||||
assign inst_sll_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0e];
|
||||
assign inst_srl_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0f];
|
||||
assign inst_sra_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h10];
|
||||
assign inst_mul_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h18];
|
||||
assign inst_mulh_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h19];
|
||||
assign inst_mulh_wu = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h1a];
|
||||
assign inst_div_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h00];
|
||||
assign inst_mod_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h01];
|
||||
assign inst_div_wu = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h02];
|
||||
assign inst_mod_wu = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h03];
|
||||
assign inst_break = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h14];
|
||||
assign inst_syscall = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h16];
|
||||
assign inst_slli_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h01];
|
||||
assign inst_srli_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h09];
|
||||
assign inst_srai_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h11];
|
||||
//assign inst_idle = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h11];
|
||||
//assign inst_invtlb = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h13];
|
||||
assign inst_dbar = op_31_26_d[6'h0e] & op_25_22_d[4'h1] & op_21_20_d[2'h3] & op_19_15_d[5'h04];
|
||||
assign inst_ibar = op_31_26_d[6'h0e] & op_25_22_d[4'h1] & op_21_20_d[2'h3] & op_19_15_d[5'h05];
|
||||
assign inst_slti = op_31_26_d[6'h00] & op_25_22_d[4'h8];
|
||||
assign inst_sltui = op_31_26_d[6'h00] & op_25_22_d[4'h9];
|
||||
assign inst_addi_w = op_31_26_d[6'h00] & op_25_22_d[4'ha];
|
||||
assign inst_andi = op_31_26_d[6'h00] & op_25_22_d[4'hd];
|
||||
assign inst_ori = op_31_26_d[6'h00] & op_25_22_d[4'he];
|
||||
assign inst_xori = op_31_26_d[6'h00] & op_25_22_d[4'hf];
|
||||
assign inst_ld_b = op_31_26_d[6'h0a] & op_25_22_d[4'h0];
|
||||
assign inst_ld_h = op_31_26_d[6'h0a] & op_25_22_d[4'h1];
|
||||
assign inst_ld_w = op_31_26_d[6'h0a] & op_25_22_d[4'h2];
|
||||
assign inst_st_b = op_31_26_d[6'h0a] & op_25_22_d[4'h4];
|
||||
assign inst_st_h = op_31_26_d[6'h0a] & op_25_22_d[4'h5];
|
||||
assign inst_st_w = op_31_26_d[6'h0a] & op_25_22_d[4'h6];
|
||||
assign inst_ld_bu = op_31_26_d[6'h0a] & op_25_22_d[4'h8];
|
||||
assign inst_ld_hu = op_31_26_d[6'h0a] & op_25_22_d[4'h9];
|
||||
//assign inst_cacop = op_31_26_d[6'h01] & op_25_22_d[4'h8];
|
||||
//assign inst_preld = op_31_26_d[6'h0a] & op_25_22_d[4'hb];
|
||||
assign inst_jirl = op_31_26_d[6'h13];
|
||||
assign inst_b = op_31_26_d[6'h14];
|
||||
assign inst_bl = op_31_26_d[6'h15];
|
||||
assign inst_beq = op_31_26_d[6'h16];
|
||||
assign inst_bne = op_31_26_d[6'h17];
|
||||
assign inst_blt = op_31_26_d[6'h18];
|
||||
assign inst_bge = op_31_26_d[6'h19];
|
||||
assign inst_bltu = op_31_26_d[6'h1a];
|
||||
assign inst_bgeu = op_31_26_d[6'h1b];
|
||||
assign inst_lu12i_w = op_31_26_d[6'h05] & ~inst[25];
|
||||
assign inst_pcaddi = op_31_26_d[6'h06] & ~inst[25];
|
||||
assign inst_pcaddu12i = op_31_26_d[6'h07] & ~inst[25];
|
||||
assign inst_csrxchg = op_31_26_d[6'h01] & ~inst[25] & ~inst[24] & (~rj_d[5'h00] & ~rj_d[5'h01]); //rj != 0,1
|
||||
assign inst_ll_w = op_31_26_d[6'h08] & ~inst[25] & ~inst[24];
|
||||
assign inst_sc_w = op_31_26_d[6'h08] & ~inst[25] & inst[24];
|
||||
assign inst_csrrd = op_31_26_d[6'h01] & ~inst[25] & ~inst[24] & rj_d[5'h00];
|
||||
assign inst_csrwr = op_31_26_d[6'h01] & ~inst[25] & ~inst[24] & rj_d[5'h01];
|
||||
assign inst_rdcntid_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h0] & op_19_15_d[5'h00] & rk_d[5'h18] & rd_d[5'h00];
|
||||
assign inst_rdcntvl_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h0] & op_19_15_d[5'h00] & rk_d[5'h18] & rj_d[5'h00] & !rd_d[5'h00];
|
||||
assign inst_rdcntvh_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h0] & op_19_15_d[5'h00] & rk_d[5'h19] & rj_d[5'h00];
|
||||
assign inst_ertn = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & rk_d[5'h0e] & rj_d[5'h00] & rd_d[5'h00];
|
||||
//assign inst_tlbsrch = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & rk_d[5'h0a] & rj_d[5'h00] & rd_d[5'h00];
|
||||
//assign inst_tlbrd = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & rk_d[5'h0b] & rj_d[5'h00] & rd_d[5'h00];
|
||||
//assign inst_tlbwr = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & rk_d[5'h0c] & rj_d[5'h00] & rd_d[5'h00];
|
||||
//assign inst_tlbfill = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & rk_d[5'h0d] & rj_d[5'h00] & rd_d[5'h00];
|
||||
|
||||
|
||||
assign src_reg_is_rd = inst_beq |
|
||||
inst_bne |
|
||||
inst_blt |
|
||||
inst_bltu |
|
||||
inst_bge |
|
||||
inst_bgeu |
|
||||
inst_st_b |
|
||||
inst_st_h |
|
||||
inst_st_w |
|
||||
inst_sc_w |
|
||||
inst_csrwr |
|
||||
inst_csrxchg;
|
||||
|
||||
assign src1_is_pc = inst_jirl |
|
||||
inst_bl |
|
||||
inst_pcaddi |
|
||||
inst_pcaddu12i;
|
||||
|
||||
assign src2_is_imm = inst_slli_w |
|
||||
inst_srli_w |
|
||||
inst_srai_w |
|
||||
inst_addi_w |
|
||||
inst_slti |
|
||||
inst_sltui |
|
||||
inst_andi |
|
||||
inst_ori |
|
||||
inst_xori |
|
||||
inst_pcaddi |
|
||||
inst_pcaddu12i |
|
||||
inst_ld_b |
|
||||
inst_ld_h |
|
||||
inst_ld_w |
|
||||
inst_ld_bu |
|
||||
inst_ld_hu |
|
||||
inst_st_b |
|
||||
inst_st_h |
|
||||
inst_st_w |
|
||||
inst_ll_w |
|
||||
inst_sc_w |
|
||||
inst_lu12i_w ;
|
||||
//inst_cacop |
|
||||
//inst_preld ;
|
||||
|
||||
assign src2_is_4 = inst_jirl |
|
||||
inst_bl;
|
||||
|
||||
assign dest_is_r1 = inst_bl;
|
||||
assign dest_is_rj = inst_rdcntid_w;
|
||||
assign dest = (dest_is_r1) ? 5'd1 :
|
||||
(dest_is_rj) ? rj :
|
||||
rd;
|
||||
|
||||
|
||||
// alu_op
|
||||
assign alu_op[ 0] = inst_add_w |
|
||||
inst_addi_w |
|
||||
//inst_ld_b |
|
||||
//inst_ld_h |
|
||||
//inst_ld_w |
|
||||
//inst_st_b |
|
||||
//inst_st_h |
|
||||
//inst_st_w |
|
||||
//inst_ld_bu |
|
||||
//inst_ld_hu |
|
||||
//inst_ll_w |
|
||||
//inst_sc_w |
|
||||
inst_jirl |
|
||||
inst_bl |
|
||||
inst_pcaddi |
|
||||
inst_pcaddu12i;
|
||||
//inst_cacop |
|
||||
//inst_preld ;
|
||||
|
||||
assign alu_op[ 1] = inst_sub_w;
|
||||
assign alu_op[ 2] = inst_slt | inst_slti;
|
||||
assign alu_op[ 3] = inst_sltu | inst_sltui;
|
||||
assign alu_op[ 4] = inst_and | inst_andi;
|
||||
assign alu_op[ 5] = inst_nor;
|
||||
assign alu_op[ 6] = inst_or | inst_ori;
|
||||
assign alu_op[ 7] = inst_xor | inst_xori;
|
||||
assign alu_op[ 8] = inst_sll_w | inst_slli_w;
|
||||
assign alu_op[ 9] = inst_srl_w | inst_srli_w;
|
||||
assign alu_op[10] = inst_sra_w | inst_srai_w;
|
||||
assign alu_op[11] = inst_lu12i_w;
|
||||
//assign alu_op[12] = inst_andn;
|
||||
//assign alu_op[13] = inst_orn;
|
||||
|
||||
// imm
|
||||
assign need_ui5 = inst_slli_w | inst_srli_w | inst_srai_w;
|
||||
assign need_si12 = inst_addi_w |
|
||||
inst_ld_b |
|
||||
inst_ld_h |
|
||||
inst_ld_w |
|
||||
inst_st_b |
|
||||
inst_st_h |
|
||||
inst_st_w |
|
||||
inst_ld_bu |
|
||||
inst_ld_hu |
|
||||
inst_slti |
|
||||
inst_sltui;
|
||||
//inst_cacop |
|
||||
//inst_preld ;
|
||||
|
||||
assign need_ui12 = inst_andi | inst_ori | inst_xori;
|
||||
assign need_si14_pc = inst_ll_w | inst_sc_w;
|
||||
assign need_si16_pc = inst_jirl |
|
||||
inst_beq |
|
||||
inst_bne |
|
||||
inst_blt |
|
||||
inst_bge |
|
||||
inst_bltu |
|
||||
inst_bgeu;
|
||||
|
||||
assign need_si20 = inst_lu12i_w | inst_pcaddu12i;
|
||||
assign need_si20_pc = inst_pcaddi;
|
||||
assign need_si26_pc = inst_b | inst_bl;
|
||||
|
||||
assign imm = ({32{need_ui5 }} & {27'b0, rk} ) |
|
||||
({32{need_si12 }} & {{20{i12[11]}}, i12} ) |
|
||||
({32{need_ui12 }} & {20'b0, i12} ) |
|
||||
({32{need_si14_pc}} & {{16{i14[13]}}, i14, 2'b0}) |
|
||||
({32{need_si16_pc}} & {{14{i16[15]}}, i16, 2'b0}) |
|
||||
({32{need_si20 }} & {i20, 12'b0} ) |
|
||||
({32{need_si20_pc}} & {{10{i20[19]}}, i20, 2'b0}) |
|
||||
({32{need_si26_pc}} & {{ 4{i26[25]}}, i26, 2'b0}) ;
|
||||
|
||||
// mul_div
|
||||
assign mul_div_op[ 0] = inst_mul_w;
|
||||
assign mul_div_op[ 1] = inst_mulh_w | inst_mulh_wu;
|
||||
assign mul_div_op[ 2] = inst_div_w | inst_div_wu;
|
||||
assign mul_div_op[ 3] = inst_mod_w | inst_mod_wu;
|
||||
|
||||
assign mul_div_sign = inst_mul_w | inst_mulh_w | inst_div_w | inst_mod_w;
|
||||
|
||||
// branch_op
|
||||
assign branch_op = {inst_beq,
|
||||
inst_bne,
|
||||
inst_blt,
|
||||
inst_bge,
|
||||
inst_bltu,
|
||||
inst_bgeu,
|
||||
inst_jirl,
|
||||
inst_bl,
|
||||
inst_b
|
||||
};
|
||||
|
||||
// load_op store_op
|
||||
assign load_op = {inst_ld_b,
|
||||
inst_ld_h,
|
||||
inst_ld_w,
|
||||
inst_ld_bu,
|
||||
inst_ld_hu,
|
||||
inst_ll_w
|
||||
};
|
||||
assign store_op = {inst_st_b,
|
||||
inst_st_h,
|
||||
inst_st_w
|
||||
};
|
||||
assign reg_we = ~inst_st_b &
|
||||
~inst_st_h &
|
||||
~inst_st_w &
|
||||
~inst_beq &
|
||||
~inst_bne &
|
||||
~inst_blt &
|
||||
~inst_bge &
|
||||
~inst_bltu &
|
||||
~inst_bgeu &
|
||||
~inst_b &
|
||||
~inst_syscall &
|
||||
//~inst_tlbsrch &
|
||||
//~inst_tlbrd &
|
||||
//~inst_tlbwr &
|
||||
//~inst_tlbfill &
|
||||
//~inst_invtlb &
|
||||
//~inst_cacop &
|
||||
//~inst_preld &
|
||||
~inst_dbar &
|
||||
~inst_ibar ;
|
||||
|
||||
|
||||
|
||||
// csr
|
||||
assign csr_we = inst_csrwr | inst_csrxchg;
|
||||
assign csr_op = {inst_csrrd,
|
||||
inst_csrwr,
|
||||
inst_csrxchg,
|
||||
inst_rdcntid_w,
|
||||
inst_rdcntvh_w,
|
||||
inst_rdcntvl_w,
|
||||
inst_sc_w
|
||||
};
|
||||
assign csr_addr = inst[23:10];
|
||||
assign csr_wdata_sel = inst_csrxchg;
|
||||
assign csr_vec_l = {25'b0, excp_adef, excp_ipe, excp_ine, inst_break, inst_syscall, inst_ertn, csr_has_int};
|
||||
|
||||
assign inst_valid = inst_add_w |
|
||||
inst_sub_w |
|
||||
inst_slt |
|
||||
inst_sltu |
|
||||
inst_nor |
|
||||
inst_and |
|
||||
inst_or |
|
||||
inst_xor |
|
||||
inst_sll_w |
|
||||
inst_srl_w |
|
||||
inst_sra_w |
|
||||
inst_mul_w |
|
||||
inst_mulh_w |
|
||||
inst_mulh_wu |
|
||||
inst_div_w |
|
||||
inst_mod_w |
|
||||
inst_div_wu |
|
||||
inst_mod_wu |
|
||||
inst_break |
|
||||
inst_syscall |
|
||||
inst_slli_w |
|
||||
inst_srli_w |
|
||||
inst_srai_w |
|
||||
//inst_idle |
|
||||
inst_slti |
|
||||
inst_sltui |
|
||||
inst_addi_w |
|
||||
inst_andi |
|
||||
inst_ori |
|
||||
inst_xori |
|
||||
inst_ld_b |
|
||||
inst_ld_h |
|
||||
inst_ld_w |
|
||||
inst_st_b |
|
||||
inst_st_h |
|
||||
inst_st_w |
|
||||
inst_ld_bu |
|
||||
inst_ld_hu |
|
||||
inst_ll_w |
|
||||
inst_sc_w |
|
||||
inst_jirl |
|
||||
inst_b |
|
||||
inst_bl |
|
||||
inst_beq |
|
||||
inst_bne |
|
||||
inst_blt |
|
||||
inst_bge |
|
||||
inst_bltu |
|
||||
inst_bgeu |
|
||||
inst_lu12i_w |
|
||||
inst_pcaddu12i |
|
||||
inst_csrrd |
|
||||
inst_csrwr |
|
||||
inst_csrxchg |
|
||||
inst_rdcntid_w |
|
||||
inst_rdcntvh_w |
|
||||
inst_rdcntvl_w |
|
||||
inst_ertn |
|
||||
//inst_cacop |
|
||||
//inst_preld |
|
||||
inst_dbar |
|
||||
inst_ibar ;
|
||||
//inst_tlbsrch |
|
||||
//inst_tlbrd |
|
||||
//inst_tlbwr |
|
||||
//inst_tlbfill |
|
||||
//(inst_invtlb && (rd == 5'd0 ||
|
||||
// rd == 5'd1 ||
|
||||
// rd == 5'd2 ||
|
||||
// rd == 5'd3 ||
|
||||
// rd == 5'd4 ||
|
||||
// rd == 5'd5 ||
|
||||
// rd == 5'd6 )); //invtlb valid op
|
||||
|
||||
|
||||
assign excp_ine = ~inst_valid;
|
||||
|
||||
assign kernel_inst = inst_csrrd |
|
||||
inst_csrwr |
|
||||
inst_csrxchg |
|
||||
//inst_cacop |
|
||||
//inst_tlbsrch |
|
||||
//inst_tlbrd |
|
||||
//inst_tlbwr |
|
||||
//inst_tlbfill |
|
||||
//inst_invtlb |
|
||||
inst_ertn ;
|
||||
//inst_idle ;
|
||||
|
||||
assign excp_ipe = kernel_inst && (csr_plv == 2'b11);
|
||||
|
||||
// rf_res from
|
||||
// assign sel_rf_res[0] = inst_jirl | inst_bl;
|
||||
// assign sel_rf_res[1] = |load_op;
|
||||
// assign sel_rf_res[2] = |csr_op;
|
||||
// assign sel_rf_res[3] = |mul_div_op;
|
||||
endmodule
|
||||
63
lacpu/rtl/mycpu/lsu.v
Normal file
63
lacpu/rtl/mycpu/lsu.v
Normal file
@@ -0,0 +1,63 @@
|
||||
module lsu(
|
||||
input [ 5:0] load_op,
|
||||
input [ 2:0] store_op,
|
||||
input [31:0] rj_value,
|
||||
input [31:0] rkd_value,
|
||||
input [31:0] imm,
|
||||
|
||||
output excp_ale,
|
||||
output data_sram_en,
|
||||
output [ 3:0] data_sram_we,
|
||||
output [31:0] data_sram_addr,
|
||||
output [31:0] data_sram_wdata
|
||||
);
|
||||
wire inst_ll_w;
|
||||
wire inst_ld_b;
|
||||
wire inst_ld_bu;
|
||||
wire inst_ld_h;
|
||||
wire inst_ld_hu;
|
||||
wire inst_ld_w;
|
||||
wire inst_st_b;
|
||||
wire inst_st_h;
|
||||
wire inst_st_w;
|
||||
|
||||
wire [31:0] addr;
|
||||
wire [ 3:0] byte_sel;
|
||||
|
||||
assign {inst_ld_b,
|
||||
inst_ld_h,
|
||||
inst_ld_w,
|
||||
inst_ld_bu,
|
||||
inst_ld_hu,
|
||||
inst_ll_w
|
||||
} = load_op;
|
||||
|
||||
assign {inst_st_b,
|
||||
inst_st_h,
|
||||
inst_st_w
|
||||
} = store_op;
|
||||
|
||||
assign addr = rj_value + imm;
|
||||
|
||||
decoder_2_4 u_decoder_2_4(
|
||||
.in (addr[1:0]),
|
||||
.out(byte_sel )
|
||||
);
|
||||
|
||||
assign excp_ale = data_sram_en & (((inst_st_b | inst_ld_b | inst_ld_bu) & 1'b0 ) |
|
||||
((inst_st_h | inst_ld_h | inst_ld_hu) & addr[0] ) |
|
||||
((inst_st_w | inst_ld_w) & (|addr[1:0])));
|
||||
|
||||
|
||||
|
||||
assign data_sram_en = (|store_op) | (|load_op);
|
||||
assign data_sram_we = inst_st_b ? byte_sel :
|
||||
inst_st_h ? {{2{byte_sel[2]}}, {2{byte_sel[0]}}} :
|
||||
inst_st_w ? { 4{byte_sel[0]}} :
|
||||
4'b0;
|
||||
assign data_sram_addr = addr;
|
||||
assign data_sram_wdata = inst_st_b ? {4{rkd_value[ 7:0]}} :
|
||||
inst_st_h ? {2{rkd_value[15:0]}} :
|
||||
inst_st_w ? rkd_value :
|
||||
32'b0;
|
||||
endmodule
|
||||
196
lacpu/rtl/mycpu/mem_stage.v
Normal file
196
lacpu/rtl/mycpu/mem_stage.v
Normal file
@@ -0,0 +1,196 @@
|
||||
module mem_stage
|
||||
#(
|
||||
parameter ES_TO_MS_BUS_WD = 271,
|
||||
parameter MS_TO_ES_BUS_WD = 38,
|
||||
parameter MS_TO_WS_BUS_WD = 102
|
||||
)
|
||||
(
|
||||
input clk,
|
||||
input reset,
|
||||
input flush,
|
||||
input [ 5:0] stall,
|
||||
|
||||
output except_en,
|
||||
output [31:0] new_pc,
|
||||
|
||||
output [ 1:0] csr_plv,
|
||||
output csr_has_int,
|
||||
|
||||
input stallreq_axi,
|
||||
|
||||
input [ES_TO_MS_BUS_WD -1:0] es_to_ms_bus,
|
||||
output [MS_TO_ES_BUS_WD -1:0] ms_to_es_bus,
|
||||
output [MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus,
|
||||
|
||||
input [31:0] data_sram_rdata
|
||||
);
|
||||
|
||||
reg [ES_TO_MS_BUS_WD -1:0] es_to_ms_bus_r;
|
||||
reg [31:0] data_sram_rdata_r;
|
||||
reg [31:0] csr_rdata_r;
|
||||
reg stall_flag;
|
||||
|
||||
wire [63:0] csr_vec;
|
||||
wire [63:0] csr_bus;
|
||||
wire [ 5:0] load_op;
|
||||
wire [ 2:0] store_op;
|
||||
wire reg_we;
|
||||
wire [ 4:0] dest;
|
||||
wire [31:0] es_result;
|
||||
wire [31:0] ms_pc;
|
||||
wire [31:0] inst;
|
||||
|
||||
wire [31:0] data_temp;
|
||||
wire [31:0] csr_result;
|
||||
wire [31:0] csr_rdata;
|
||||
|
||||
wire inst_ll_w;
|
||||
wire inst_ld_b;
|
||||
wire inst_ld_bu;
|
||||
wire inst_ld_h;
|
||||
wire inst_ld_hu;
|
||||
wire inst_ld_w;
|
||||
|
||||
wire [ 3:0] byte_sel;
|
||||
wire [31:0] ms_result;
|
||||
|
||||
wire csr_we;
|
||||
wire csr_wdata_sel;
|
||||
wire [ 6:0] csr_op;
|
||||
wire [13:0] csr_addr;
|
||||
wire [31:0] csr_wdata;
|
||||
|
||||
|
||||
wire [31:0] src1;
|
||||
|
||||
wire [31:0] ms_final_result;
|
||||
|
||||
assign {csr_vec ,//270:207
|
||||
csr_bus ,//206:143
|
||||
load_op ,//142:137
|
||||
store_op ,//136:134
|
||||
reg_we ,//133:133
|
||||
dest ,//132:128
|
||||
es_result,//127:96
|
||||
src1 ,//95 :64
|
||||
ms_pc ,//63 :32
|
||||
inst //31 :0
|
||||
} = es_to_ms_bus_r;
|
||||
|
||||
assign ms_to_es_bus = {reg_we,
|
||||
dest,
|
||||
ms_final_result
|
||||
};
|
||||
|
||||
assign ms_to_ws_bus = {reg_we ,//101:101
|
||||
dest ,//100:96
|
||||
ms_final_result ,//95 :64
|
||||
ms_pc ,//63 :32
|
||||
inst //31 :0
|
||||
};
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
es_to_ms_bus_r <= 0;
|
||||
end
|
||||
else if (flush) begin
|
||||
es_to_ms_bus_r <= 0;
|
||||
end
|
||||
else if (stall[3]&(!stall[4])) begin
|
||||
es_to_ms_bus_r <= 0;
|
||||
end
|
||||
else if (!stall[3]) begin
|
||||
es_to_ms_bus_r <= es_to_ms_bus;
|
||||
end
|
||||
end
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
data_sram_rdata_r <= 0;
|
||||
csr_rdata_r <= 0;
|
||||
stall_flag <= 1'b0;
|
||||
end
|
||||
else if (flush) begin
|
||||
data_sram_rdata_r <= 0;
|
||||
csr_rdata_r <= 0;
|
||||
stall_flag <= 1'b0;
|
||||
end
|
||||
else if (!stall[3]) begin
|
||||
data_sram_rdata_r <= data_sram_rdata;
|
||||
csr_rdata_r <= csr_rdata;
|
||||
stall_flag <= 1'b0;
|
||||
end
|
||||
else if (stall_flag) begin
|
||||
|
||||
end
|
||||
else if (stall[3]&stall[4])begin
|
||||
data_sram_rdata_r <= data_sram_rdata;
|
||||
csr_rdata_r <= csr_rdata;
|
||||
stall_flag <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
assign data_temp = stall_flag ? data_sram_rdata_r : data_sram_rdata;
|
||||
assign csr_result = stall_flag ? csr_rdata_r : csr_rdata;
|
||||
|
||||
assign {inst_ld_b,
|
||||
inst_ld_h,
|
||||
inst_ld_w,
|
||||
inst_ld_bu,
|
||||
inst_ld_hu,
|
||||
inst_ll_w
|
||||
} = load_op;
|
||||
|
||||
decoder_2_4 u_decoder_2_4(
|
||||
.in (es_result[1:0]),
|
||||
.out(byte_sel )
|
||||
);
|
||||
|
||||
assign ms_result = (inst_ld_b & byte_sel[0]) ? {{24{data_temp[ 7]}}, data_temp[ 7: 0]} :
|
||||
(inst_ld_b & byte_sel[1]) ? {{24{data_temp[15]}}, data_temp[15: 8]} :
|
||||
(inst_ld_b & byte_sel[2]) ? {{24{data_temp[23]}}, data_temp[23:16]} :
|
||||
(inst_ld_b & byte_sel[3]) ? {{24{data_temp[31]}}, data_temp[31:24]} :
|
||||
(inst_ld_bu & byte_sel[0]) ? { 24'b0, data_temp[ 7: 0]} :
|
||||
(inst_ld_bu & byte_sel[1]) ? { 24'b0, data_temp[15: 8]} :
|
||||
(inst_ld_bu & byte_sel[2]) ? { 24'b0, data_temp[23:16]} :
|
||||
(inst_ld_bu & byte_sel[3]) ? { 24'b0, data_temp[31:24]} :
|
||||
(inst_ld_h & byte_sel[0]) ? {{16{data_temp[15]}}, data_temp[15: 0]} :
|
||||
(inst_ld_h & byte_sel[2]) ? {{16{data_temp[31]}}, data_temp[31:16]} :
|
||||
(inst_ld_hu & byte_sel[0]) ? { 16'b0, data_temp[15: 0]} :
|
||||
(inst_ld_hu & byte_sel[2]) ? { 16'b0, data_temp[31:16]} :
|
||||
(inst_ld_w & byte_sel[0]) ? data_temp :
|
||||
32'b0; // inst_ll ?
|
||||
|
||||
assign {csr_we,
|
||||
csr_wdata_sel,
|
||||
csr_op,
|
||||
csr_addr,
|
||||
csr_wdata
|
||||
} = csr_bus;
|
||||
|
||||
csr u_csr(
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.stall (stall[3]&stall[4] ),
|
||||
.pc (ms_pc ),
|
||||
.src1 (src1 ),
|
||||
.error_va (es_result ),
|
||||
.plv_out (csr_plv ),
|
||||
.has_int_out (csr_has_int ),
|
||||
.csr_we (csr_we ),
|
||||
.csr_vec (csr_vec ),
|
||||
.csr_op (csr_op ),
|
||||
.csr_addr (csr_addr ),
|
||||
.csr_wdata_sel (csr_wdata_sel ),
|
||||
.csr_wdata (csr_wdata ),
|
||||
.csr_rdata (csr_rdata ),
|
||||
.except_en (except_en ),
|
||||
.new_pc (new_pc ),
|
||||
.stallreq_axi (stallreq_axi )
|
||||
);
|
||||
|
||||
assign ms_final_result = (|load_op) ? ms_result :
|
||||
(|csr_op ) ? csr_result :
|
||||
es_result;
|
||||
|
||||
endmodule
|
||||
21
lacpu/rtl/mycpu/mmu.v
Normal file
21
lacpu/rtl/mycpu/mmu.v
Normal 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
|
||||
47
lacpu/rtl/mycpu/mul.v
Normal file
47
lacpu/rtl/mycpu/mul.v
Normal file
@@ -0,0 +1,47 @@
|
||||
module mul(
|
||||
input clk,
|
||||
input reset,
|
||||
output stallreq,
|
||||
input in_valid,
|
||||
output out_valid,
|
||||
|
||||
input [31:0] a,
|
||||
input [31:0] b,
|
||||
|
||||
output reg [31:0] result_h,
|
||||
output reg [31:0] result_l
|
||||
);
|
||||
reg [ 5:0] cnt;
|
||||
wire [31:0] add_result;
|
||||
wire carry;
|
||||
always @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
cnt <= 0;
|
||||
end
|
||||
else if (cnt != 0) begin
|
||||
cnt <= cnt - 1;
|
||||
end
|
||||
else if (in_valid) begin
|
||||
cnt <= 32;
|
||||
end
|
||||
end
|
||||
|
||||
assign {carry, add_result} = result_h + (result_l[0] ? a : 0);
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
result_h <= 0;
|
||||
result_l <= 0;
|
||||
end
|
||||
else if (cnt != 0) begin
|
||||
{result_h, result_l} <= {carry, add_result, result_l[31:1]};
|
||||
end
|
||||
else if (in_valid) begin
|
||||
result_h <= 0;
|
||||
result_l <= b;
|
||||
end
|
||||
end
|
||||
|
||||
assign out_valid = (cnt==0);
|
||||
assign stallreq = in_valid | (~(cnt==0));
|
||||
endmodule
|
||||
66
lacpu/rtl/mycpu/mul_div_lock.v
Normal file
66
lacpu/rtl/mycpu/mul_div_lock.v
Normal file
@@ -0,0 +1,66 @@
|
||||
module mul_div_lock (
|
||||
input clk,
|
||||
input reset,
|
||||
input [ 5:0] stall,
|
||||
input [31:0] a,
|
||||
input [31:0] b,
|
||||
input mul_en,
|
||||
input div_en,
|
||||
input stallreq_for_mul,
|
||||
input stallreq_for_div,
|
||||
|
||||
output [31:0] a_locked,
|
||||
output [31:0] b_locked,
|
||||
output mul_en_locked,
|
||||
output div_en_locked
|
||||
);
|
||||
reg first_enable;
|
||||
reg mul_en_musk;
|
||||
reg div_en_musk;
|
||||
reg [31:0] a_buffer;
|
||||
reg [31:0] b_buffer;
|
||||
|
||||
wire stallreq = stallreq_for_mul | stallreq_for_div;
|
||||
|
||||
assign mul_en_locked = mul_en & mul_en_musk;
|
||||
assign div_en_locked = div_en & div_en_musk;
|
||||
|
||||
assign a_locked = first_enable ? a : a_buffer;
|
||||
assign b_locked = first_enable ? b : b_buffer;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
a_buffer <= 0;
|
||||
b_buffer <= 0;
|
||||
mul_en_musk <= 1;
|
||||
div_en_musk <= 1;
|
||||
|
||||
first_enable <= 1;
|
||||
end
|
||||
else if (mul_en & first_enable) begin
|
||||
a_buffer <= a;
|
||||
b_buffer <= b;
|
||||
mul_en_musk <= 0;
|
||||
div_en_musk <= 1;
|
||||
|
||||
first_enable <= 0;
|
||||
end
|
||||
else if (div_en & first_enable) begin
|
||||
a_buffer <= a;
|
||||
b_buffer <= b;
|
||||
mul_en_musk <= 1;
|
||||
div_en_musk <= 0;
|
||||
|
||||
first_enable <= 0;
|
||||
end
|
||||
else if (!stallreq & (mul_en|div_en) & !first_enable & !stall[2]) begin
|
||||
a_buffer <= 0;
|
||||
b_buffer <= 0;
|
||||
mul_en_musk <= 1;
|
||||
div_en_musk <= 1;
|
||||
|
||||
first_enable <= 1;
|
||||
end
|
||||
|
||||
end
|
||||
endmodule
|
||||
87
lacpu/rtl/mycpu/mul_div_top.v
Normal file
87
lacpu/rtl/mycpu/mul_div_top.v
Normal file
@@ -0,0 +1,87 @@
|
||||
module mul_div_top(
|
||||
input clk,
|
||||
input reset,
|
||||
input [ 5:0] stall,
|
||||
output stallreq,
|
||||
|
||||
input [ 3:0] mul_div_op,
|
||||
input mul_div_sign,
|
||||
|
||||
input [31:0] a,
|
||||
input [31:0] b,
|
||||
|
||||
output [31:0] mul_div_result
|
||||
);
|
||||
wire stallreq_for_mul;
|
||||
wire stallreq_for_div;
|
||||
wire sign_flag;
|
||||
wire [31:0] src_a;
|
||||
wire [31:0] src_b;
|
||||
wire [31:0] result_h;
|
||||
wire [31:0] result_l;
|
||||
wire [31:0] quotient;
|
||||
wire [31:0] remainder;
|
||||
|
||||
wire mul_en;
|
||||
wire div_en;
|
||||
|
||||
wire [31:0] a_locked;
|
||||
wire [31:0] b_locked;
|
||||
wire mul_en_locked;
|
||||
wire div_en_locked;
|
||||
|
||||
assign mul_en = mul_div_op[0] | mul_div_op[1];
|
||||
assign div_en = mul_div_op[2] | mul_div_op[3];
|
||||
|
||||
assign sign_flag = a[31] ^ b[31];
|
||||
assign src_a = (mul_div_sign & a[31]) ? (~a[31:0] + 1'b1) : a;
|
||||
assign src_b = (mul_div_sign & b[31]) ? (~b[31:0] + 1'b1) : b;
|
||||
|
||||
mul_div_lock u_mul_div_lock(
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.stall (stall ),
|
||||
.a (src_a ),
|
||||
.b (src_b ),
|
||||
.mul_en (mul_en ),
|
||||
.div_en (div_en ),
|
||||
.stallreq_for_mul (stallreq_for_mul ),
|
||||
.stallreq_for_div (stallreq_for_div ),
|
||||
.a_locked (a_locked ),
|
||||
.b_locked (b_locked ),
|
||||
.mul_en_locked (mul_en_locked ),
|
||||
.div_en_locked (div_en_locked )
|
||||
);
|
||||
|
||||
mul u_mul(
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.stallreq (stallreq_for_mul),
|
||||
.in_valid (mul_en_locked ),
|
||||
.out_valid (),
|
||||
.a (a_locked ),
|
||||
.b (b_locked ),
|
||||
.result_h (result_h ),
|
||||
.result_l (result_l )
|
||||
);
|
||||
|
||||
div u_div(
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.stallreq (stallreq_for_div),
|
||||
.in_valid (div_en_locked ),
|
||||
.out_valid (),
|
||||
.a (a_locked ),
|
||||
.b (b_locked ),
|
||||
.quotient (quotient ),
|
||||
.remainder (remainder )
|
||||
);
|
||||
|
||||
assign stallreq = stallreq_for_mul | stallreq_for_div;
|
||||
assign mul_div_result = mul_div_op[0] ? (mul_div_sign & (a[31] ^ b[31]) & |result_l ) ? { ~result_l[31:0] + 1'b1} : result_l :
|
||||
mul_div_op[1] ? (mul_div_sign & (a[31] ^ b[31]) & |result_h ) ? {a[31] ^ b[31], ~result_h[30:0] } : result_h :
|
||||
mul_div_op[2] ? (mul_div_sign & (a[31] ^ b[31]) & |quotient ) ? {a[31] ^ b[31], ~quotient[30:0] + 1'b1} : quotient :
|
||||
mul_div_op[3] ? (mul_div_sign & a[31] & |remainder) ? {a[31] , ~remainder[30:0] + 1'b1} : remainder :
|
||||
32'b0;
|
||||
|
||||
endmodule
|
||||
168
lacpu/rtl/mycpu/mycpu_core.v
Normal file
168
lacpu/rtl/mycpu/mycpu_core.v
Normal file
@@ -0,0 +1,168 @@
|
||||
`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 ),
|
||||
.stallreq_axi (stallreq_cache ),
|
||||
|
||||
.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 (stallreq_cache ), // TODO!
|
||||
.stallreq_cache (stallreq_cache ),
|
||||
.flush (flush ),
|
||||
.stall (stall )
|
||||
);
|
||||
|
||||
endmodule
|
||||
309
lacpu/rtl/mycpu/mycpu_top.v
Normal file
309
lacpu/rtl/mycpu/mycpu_top.v
Normal file
@@ -0,0 +1,309 @@
|
||||
`default_nettype wire
|
||||
|
||||
module mycpu_top
|
||||
#(
|
||||
parameter HIT_WD = 2,
|
||||
parameter LRU_WD = 1,
|
||||
parameter CACHELINE_WD = 512
|
||||
)
|
||||
(
|
||||
input aclk,
|
||||
input aresetn,
|
||||
output timer_int,
|
||||
|
||||
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,
|
||||
output [ 4:0] debug_wb_rf_wnum,
|
||||
output [31:0] debug_wb_rf_wdata
|
||||
);
|
||||
|
||||
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 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 clk;
|
||||
wire resetn;
|
||||
|
||||
assign clk = aclk;
|
||||
assign resetn = aresetn;
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
// 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 )
|
||||
|
||||
);
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
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 )
|
||||
);
|
||||
|
||||
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;
|
||||
|
||||
|
||||
// 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 )
|
||||
);
|
||||
|
||||
|
||||
// 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
|
||||
49
lacpu/rtl/mycpu/pip_ctrl.v
Normal file
49
lacpu/rtl/mycpu/pip_ctrl.v
Normal file
@@ -0,0 +1,49 @@
|
||||
`define StallBus 6
|
||||
module pip_ctrl(
|
||||
input reset,
|
||||
input except_en,
|
||||
input stallreq_ds,
|
||||
input stallreq_es,
|
||||
input stallreq_axi,
|
||||
input stallreq_cache,
|
||||
output reg flush,
|
||||
output reg [`StallBus-1:0] stall
|
||||
);
|
||||
//stall[0] --?
|
||||
//stall[1] --?
|
||||
//stall[2] --id
|
||||
//stall[3]
|
||||
//stall[4]
|
||||
//stall[5]
|
||||
always @ (*) begin
|
||||
if (reset) begin
|
||||
flush = 0;
|
||||
stall = `StallBus'b000000;
|
||||
end
|
||||
else if (stallreq_axi) begin
|
||||
flush = 0;
|
||||
stall = `StallBus'b111111;
|
||||
end
|
||||
else if (except_en) begin
|
||||
flush = 1;
|
||||
stall = `StallBus'b0;
|
||||
end
|
||||
//id段发生暂停,此时id及之前暂停
|
||||
else if (stallreq_ds) begin
|
||||
flush = 0;
|
||||
stall = `StallBus'b000111;
|
||||
end
|
||||
else if (stallreq_es) begin
|
||||
flush = 0;
|
||||
stall = `StallBus'b011111;
|
||||
end
|
||||
// else if(stallreq_cache) begin
|
||||
// flush = 0;
|
||||
// stall = `StallBus'b111111;
|
||||
// end
|
||||
else begin
|
||||
flush = 0;
|
||||
stall = `StallBus'b000000;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
68
lacpu/rtl/mycpu/regfile.v
Normal file
68
lacpu/rtl/mycpu/regfile.v
Normal file
@@ -0,0 +1,68 @@
|
||||
module regfile(
|
||||
input clk,
|
||||
input reset,
|
||||
// READ PORT 1
|
||||
input [ 4:0] raddr1,
|
||||
output [31:0] rdata1,
|
||||
// READ PORT 2
|
||||
input [ 4:0] raddr2,
|
||||
output [31:0] rdata2,
|
||||
// WRITE PORT
|
||||
input we, //write enable, HIGH valid
|
||||
input [ 4:0] waddr,
|
||||
input [31:0] wdata
|
||||
);
|
||||
reg [31:0] rf[31:0];
|
||||
|
||||
//WRITE
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
rf[ 0] <= 32'b0;
|
||||
rf[ 1] <= 32'b0;
|
||||
rf[ 2] <= 32'b0;
|
||||
rf[ 3] <= 32'b0;
|
||||
rf[ 4] <= 32'b0;
|
||||
rf[ 5] <= 32'b0;
|
||||
rf[ 6] <= 32'b0;
|
||||
rf[ 7] <= 32'b0;
|
||||
rf[ 8] <= 32'b0;
|
||||
rf[ 9] <= 32'b0;
|
||||
rf[10] <= 32'b0;
|
||||
rf[11] <= 32'b0;
|
||||
rf[12] <= 32'b0;
|
||||
rf[13] <= 32'b0;
|
||||
rf[14] <= 32'b0;
|
||||
rf[15] <= 32'b0;
|
||||
rf[16] <= 32'b0;
|
||||
rf[17] <= 32'b0;
|
||||
rf[18] <= 32'b0;
|
||||
rf[19] <= 32'b0;
|
||||
rf[20] <= 32'b0;
|
||||
rf[21] <= 32'b0;
|
||||
rf[22] <= 32'b0;
|
||||
rf[23] <= 32'b0;
|
||||
rf[24] <= 32'b0;
|
||||
rf[25] <= 32'b0;
|
||||
rf[26] <= 32'b0;
|
||||
rf[27] <= 32'b0;
|
||||
rf[28] <= 32'b0;
|
||||
rf[29] <= 32'b0;
|
||||
rf[30] <= 32'b0;
|
||||
rf[31] <= 32'b0;
|
||||
end
|
||||
else if (we) begin
|
||||
rf[waddr]<= wdata;
|
||||
end
|
||||
end
|
||||
|
||||
//READ OUT 1
|
||||
assign rdata1 = (raddr1==5'b0 ) ? 32'b0 :
|
||||
(raddr1==waddr) & we ? wdata :
|
||||
rf[raddr1];
|
||||
|
||||
//READ OUT 2
|
||||
assign rdata2 = (raddr2==5'b0 ) ? 32'b0 :
|
||||
(raddr2==waddr) & we ? wdata :
|
||||
rf[raddr2];
|
||||
|
||||
endmodule
|
||||
182
lacpu/rtl/mycpu/tlb.v
Normal file
182
lacpu/rtl/mycpu/tlb.v
Normal file
@@ -0,0 +1,182 @@
|
||||
module tlb
|
||||
(
|
||||
input clk,
|
||||
|
||||
//search port 1
|
||||
input [12:0] s0_vppn,
|
||||
input [9:0] s0_asid,
|
||||
input s0_odd,
|
||||
output reg [11:0] s0_ppn,
|
||||
output reg [3:0] s0_index,
|
||||
output reg s0_found,
|
||||
//search port 2
|
||||
input [12:0] s1_vppn,
|
||||
input [9:0] s1_asid,
|
||||
input s1_odd,
|
||||
output reg [11:0] s1_ppn,
|
||||
output reg [3:0] s1_index,
|
||||
output reg s1_found,
|
||||
|
||||
//read port
|
||||
input [3:0] r_index,
|
||||
output [12:0] r_vppn,
|
||||
output [5:0] r_ps,
|
||||
output r_g,
|
||||
output [9:0] r_asid,
|
||||
output r_e,
|
||||
output [11:0] r_ppn0,
|
||||
output [1:0] r_plv0,
|
||||
output [1:0] r_mat0,
|
||||
output r_d0,
|
||||
output r_v0,
|
||||
output [11:0] r_ppn1,
|
||||
output [1:0] r_plv1,
|
||||
output [1:0] r_mat1,
|
||||
output r_d1,
|
||||
output r_v1,
|
||||
|
||||
|
||||
//write port
|
||||
input we,
|
||||
input [3:0] w_index,
|
||||
input [12:0] w_vppn,
|
||||
input [5:0] w_ps,
|
||||
input w_g,
|
||||
input [9:0] w_asid,
|
||||
input w_e,
|
||||
input [11:0] w_ppn0,
|
||||
input [1:0] w_plv0,
|
||||
input [1:0] w_mat0,
|
||||
input w_d0,
|
||||
input w_v0,
|
||||
input [11:0] w_ppn1,
|
||||
input [1:0] w_plv1,
|
||||
input [1:0] w_mat1,
|
||||
input w_d1,
|
||||
input w_v1
|
||||
|
||||
);
|
||||
|
||||
reg [12:0] tlb_vppn [0:15];
|
||||
reg [5:0] tlb_ps [0:15];
|
||||
reg tlb_g [0:15];
|
||||
reg [9:0] tlb_asid [0:15];
|
||||
reg tlb_e [0:15];
|
||||
reg [11:0] tlb_ppn0 [0:15];
|
||||
reg [1:0] tlb_plv0 [0:15];
|
||||
reg [1:0] tlb_mat0 [0:15];
|
||||
reg tlb_d0 [0:15];
|
||||
reg tlb_v0 [0:15];
|
||||
reg [11:0] tlb_ppn1 [0:15];
|
||||
reg [1:0] tlb_plv1 [0:15];
|
||||
reg [1:0] tlb_mat1 [0:15];
|
||||
reg tlb_d1 [0:15];
|
||||
reg tlb_v1 [0:15];
|
||||
|
||||
|
||||
//search
|
||||
integer i;
|
||||
reg match0 [0:15];
|
||||
reg match1 [0:15];
|
||||
always @(*) begin
|
||||
for(i = 0; i < 16; i++) begin
|
||||
match0[i] = (s0_vppn == tlb_vppn[i]) && ((s0_asid == tlb_asid[i]) || tlb_g[i]);
|
||||
match1[i] = (s1_vppn == tlb_vppn[i]) && ((s1_asid == tlb_asid[i]) || tlb_g[i]);
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
s0_found = match0[0];
|
||||
s1_found = match1[0];
|
||||
for(i = 1; i < 16; i++) begin
|
||||
s0_found = match0[i] || s0_found;
|
||||
s1_found = match1[i] || s1_found;
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
case (1'b1)
|
||||
match0[0]: begin s0_ppn = s0_odd ? tlb_ppn0[0] : tlb_ppn1[0]; s0_index = 4'd0; end
|
||||
match0[1]: begin s0_ppn = s0_odd ? tlb_ppn0[1] : tlb_ppn1[1]; s0_index = 4'd1; end
|
||||
match0[2]: begin s0_ppn = s0_odd ? tlb_ppn0[2] : tlb_ppn1[2]; s0_index = 4'd2; end
|
||||
match0[3]: begin s0_ppn = s0_odd ? tlb_ppn0[3] : tlb_ppn1[3]; s0_index = 4'd3; end
|
||||
match0[4]: begin s0_ppn = s0_odd ? tlb_ppn0[4] : tlb_ppn1[4]; s0_index = 4'd4; end
|
||||
match0[5]: begin s0_ppn = s0_odd ? tlb_ppn0[5] : tlb_ppn1[5]; s0_index = 4'd5; end
|
||||
match0[6]: begin s0_ppn = s0_odd ? tlb_ppn0[6] : tlb_ppn1[6]; s0_index = 4'd6; end
|
||||
match0[7]: begin s0_ppn = s0_odd ? tlb_ppn0[7] : tlb_ppn1[7]; s0_index = 4'd7; end
|
||||
match0[8]: begin s0_ppn = s0_odd ? tlb_ppn0[8] : tlb_ppn1[8]; s0_index = 4'd8; end
|
||||
match0[9]: begin s0_ppn = s0_odd ? tlb_ppn0[9] : tlb_ppn1[9]; s0_index = 4'd9; end
|
||||
match0[10]: begin s0_ppn = s0_odd ? tlb_ppn0[10] : tlb_ppn1[10]; s0_index = 4'd10; end
|
||||
match0[11]: begin s0_ppn = s0_odd ? tlb_ppn0[11] : tlb_ppn1[11]; s0_index = 4'd11; end
|
||||
match0[12]: begin s0_ppn = s0_odd ? tlb_ppn0[12] : tlb_ppn1[12]; s0_index = 4'd12; end
|
||||
match0[13]: begin s0_ppn = s0_odd ? tlb_ppn0[13] : tlb_ppn1[13]; s0_index = 4'd13; end
|
||||
match0[14]: begin s0_ppn = s0_odd ? tlb_ppn0[14] : tlb_ppn1[14]; s0_index = 4'd14; end
|
||||
match0[15]: begin s0_ppn = s0_odd ? tlb_ppn0[15] : tlb_ppn1[15]; s0_index = 4'd15; end
|
||||
default: begin
|
||||
s0_ppn = 12'b0;
|
||||
s0_index = 4'd0;
|
||||
end
|
||||
endcase
|
||||
|
||||
case (1'b1)
|
||||
match1[0]: begin s1_ppn = s1_odd ? tlb_ppn0[0] : tlb_ppn1[0]; s1_index = 4'd0; end
|
||||
match1[1]: begin s1_ppn = s1_odd ? tlb_ppn0[1] : tlb_ppn1[1]; s1_index = 4'd1; end
|
||||
match1[2]: begin s1_ppn = s1_odd ? tlb_ppn0[2] : tlb_ppn1[2]; s1_index = 4'd2; end
|
||||
match1[3]: begin s1_ppn = s1_odd ? tlb_ppn0[3] : tlb_ppn1[3]; s1_index = 4'd3; end
|
||||
match1[4]: begin s1_ppn = s1_odd ? tlb_ppn0[4] : tlb_ppn1[4]; s1_index = 4'd4; end
|
||||
match1[5]: begin s1_ppn = s1_odd ? tlb_ppn0[5] : tlb_ppn1[5]; s1_index = 4'd5; end
|
||||
match1[6]: begin s1_ppn = s1_odd ? tlb_ppn0[6] : tlb_ppn1[6]; s1_index = 4'd6; end
|
||||
match1[7]: begin s1_ppn = s1_odd ? tlb_ppn0[7] : tlb_ppn1[7]; s1_index = 4'd7; end
|
||||
match1[8]: begin s1_ppn = s1_odd ? tlb_ppn0[8] : tlb_ppn1[8]; s1_index = 4'd8; end
|
||||
match1[9]: begin s1_ppn = s1_odd ? tlb_ppn0[9] : tlb_ppn1[9]; s1_index = 4'd9; end
|
||||
match1[10]: begin s1_ppn = s1_odd ? tlb_ppn0[10] : tlb_ppn1[10]; s1_index = 4'd10; end
|
||||
match1[11]: begin s1_ppn = s1_odd ? tlb_ppn0[11] : tlb_ppn1[11]; s1_index = 4'd11; end
|
||||
match1[12]: begin s1_ppn = s1_odd ? tlb_ppn0[12] : tlb_ppn1[12]; s1_index = 4'd12; end
|
||||
match1[13]: begin s1_ppn = s1_odd ? tlb_ppn0[13] : tlb_ppn1[13]; s1_index = 4'd13; end
|
||||
match1[14]: begin s1_ppn = s1_odd ? tlb_ppn0[14] : tlb_ppn1[14]; s1_index = 4'd14; end
|
||||
match1[15]: begin s1_ppn = s1_odd ? tlb_ppn0[15] : tlb_ppn1[15]; s1_index = 4'd15; end
|
||||
default: begin
|
||||
s1_ppn = 12'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
//read
|
||||
assign r_vppn = (we && w_index == r_index) ? w_vppn : tlb_vppn[r_index];
|
||||
assign r_ps = (we && w_index == r_index) ? w_ps : tlb_ps[r_index];
|
||||
assign r_g = (we && w_index == r_index) ? w_g : tlb_g[r_index];
|
||||
assign r_asid = (we && w_index == r_index) ? w_asid : tlb_asid[r_index];
|
||||
assign r_e = (we && w_index == r_index) ? w_e : tlb_e[r_index];
|
||||
assign r_ppn0 = (we && w_index == r_index) ? w_ppn0 : tlb_ppn0[r_index];
|
||||
assign r_plv0 = (we && w_index == r_index) ? w_plv0 : tlb_plv0[r_index];
|
||||
assign r_mat0 = (we && w_index == r_index) ? w_mat0 : tlb_mat0[r_index];
|
||||
assign r_d0 = (we && w_index == r_index) ? w_d0 : tlb_d0[r_index];
|
||||
assign r_v0 = (we && w_index == r_index) ? w_v0 : tlb_v0[r_index];
|
||||
assign r_ppn1 = (we && w_index == r_index) ? w_ppn1 : tlb_ppn1[r_index];
|
||||
assign r_plv1 = (we && w_index == r_index) ? w_plv1 : tlb_plv1[r_index];
|
||||
assign r_mat1 = (we && w_index == r_index) ? w_mat1 : tlb_mat1[r_index];
|
||||
assign r_d1 = (we && w_index == r_index) ? w_d1 : tlb_d1[r_index];
|
||||
assign r_v1 = (we && w_index == r_index) ? w_v1 : tlb_v1[r_index];
|
||||
|
||||
//write
|
||||
always @(posedge clk) begin
|
||||
if(we) begin
|
||||
tlb_vppn[w_index] <= w_vppn;
|
||||
tlb_ps[w_index] <= w_ps;
|
||||
tlb_g[w_index] <= w_g;
|
||||
tlb_asid[w_index] <= w_asid;
|
||||
tlb_e[w_index] <= w_e;
|
||||
tlb_ppn0[w_index] <= w_ppn0;
|
||||
tlb_plv0[w_index] <= w_plv0;
|
||||
tlb_mat0[w_index] <= w_mat0;
|
||||
tlb_d0[w_index] <= w_d0;
|
||||
tlb_v0[w_index] <= w_v0;
|
||||
tlb_ppn1[w_index] <= w_ppn1;
|
||||
tlb_plv1[w_index] <= w_plv1;
|
||||
tlb_mat1[w_index] <= w_mat1;
|
||||
tlb_d1[w_index] <= w_d1;
|
||||
tlb_v1[w_index] <= w_v1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
54
lacpu/rtl/mycpu/tools.v
Normal file
54
lacpu/rtl/mycpu/tools.v
Normal file
@@ -0,0 +1,54 @@
|
||||
`default_nettype wire
|
||||
module decoder_2_4(
|
||||
input [ 1:0] in,
|
||||
output [ 3:0] out
|
||||
);
|
||||
|
||||
genvar i;
|
||||
generate for (i=0; i<4; i=i+1) begin : gen_for_dec_2_4
|
||||
assign out[i] = (in == i);
|
||||
end endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module decoder_4_16(
|
||||
input [ 3:0] in,
|
||||
output [15:0] out
|
||||
);
|
||||
|
||||
genvar i;
|
||||
generate for (i=0; i<16; i=i+1) begin : gen_for_dec_4_16
|
||||
assign out[i] = (in == i);
|
||||
end endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module decoder_5_32(
|
||||
input [ 4:0] in,
|
||||
output [31:0] out
|
||||
);
|
||||
|
||||
genvar i;
|
||||
generate for (i=0; i<32; i=i+1) begin : gen_for_dec_5_32
|
||||
assign out[i] = (in == i);
|
||||
end endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module decoder_6_64(
|
||||
input [ 5:0] in,
|
||||
output [63:0] out
|
||||
);
|
||||
|
||||
genvar i;
|
||||
generate for (i=0; i<64; i=i+1) begin : gen_for_dec_6_64 //bug7
|
||||
assign out[i] = (in == i);
|
||||
end endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
131
lacpu/rtl/mycpu/uncache.v
Normal file
131
lacpu/rtl/mycpu/uncache.v
Normal 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
|
||||
68
lacpu/rtl/mycpu/wb_stage.v
Normal file
68
lacpu/rtl/mycpu/wb_stage.v
Normal file
@@ -0,0 +1,68 @@
|
||||
module wb_stage
|
||||
#(
|
||||
parameter MS_TO_WS_BUS_WD = 102,
|
||||
parameter WS_TO_RF_BUS_WD = 38,
|
||||
parameter WS_TO_ES_BUS_WD = 38
|
||||
)
|
||||
(
|
||||
input clk,
|
||||
input reset,
|
||||
input flush,
|
||||
input [5:0] stall,
|
||||
|
||||
input [MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus,
|
||||
output [WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus,
|
||||
output [WS_TO_ES_BUS_WD -1:0] ws_to_es_bus,
|
||||
|
||||
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 [MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus_r;
|
||||
|
||||
wire reg_we;
|
||||
wire [ 4:0] dest;
|
||||
wire [31:0] ms_final_result;
|
||||
wire [31:0] ws_pc;
|
||||
wire [31:0] inst;
|
||||
|
||||
assign {reg_we ,//101:101
|
||||
dest ,//100:96
|
||||
ms_final_result ,//95 :64
|
||||
ws_pc ,//63 :32
|
||||
inst //31 :0
|
||||
} = ms_to_ws_bus_r;
|
||||
|
||||
assign ws_to_rf_bus = {reg_we,
|
||||
dest,
|
||||
ms_final_result
|
||||
};
|
||||
|
||||
assign ws_to_es_bus = {reg_we,
|
||||
dest,
|
||||
ms_final_result
|
||||
};
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (reset) begin
|
||||
ms_to_ws_bus_r <= 0;
|
||||
end
|
||||
else if (flush) begin
|
||||
ms_to_ws_bus_r <= 0;
|
||||
end
|
||||
else if (stall[4]&(!stall[5])) begin
|
||||
ms_to_ws_bus_r <= 0;
|
||||
end
|
||||
else if (!stall[4]) begin
|
||||
ms_to_ws_bus_r <= ms_to_ws_bus;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user