代码拉取完成,页面将自动刷新
同步操作将从 ysyx_yiyao/ysyx_040991 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
`define ysyx_040991_BR_BUS_WD 65
`define ysyx_040991_FS_TO_DS_BUS_WD 96
`define ysyx_040991_DS_TO_ES_BUS_WD 283
`define ysyx_040991_ES_TO_MS_BUS_WD 245
`define ysyx_040991_MS_TO_WS_BUS_WD 231
`define ysyx_040991_WS_TO_RF_BUS_WD 70
`define ysyx_040991_ES_FORWARDING_BUS_WD 71
`define ysyx_040991_MS_FORWARDING_BUS_WD 71
`define ysyx_040991_WS_FORWARDING_BUS_WD 70
`define ysyx_040991_CSR_FORWARDING_BUS_WD 77
`define ysyx_040991_VADDR_WIDTH 64
`define ysyx_040991_INST_WIDTH 32
`define ysyx_040991_DATA_WIDTH 64
// privilege definitions
`define ysyx_040991_EXCEPTION_WD 6
`define ysyx_040991_CSR_MSTATUS_ADDR 12'h300
`define ysyx_040991_CSR_MISA_ADDR 12'h301
`define ysyx_040991_CSR_MIE_ADDR 12'h304
`define ysyx_040991_CSR_MTVEC_ADDR 12'h305
`define ysyx_040991_CSR_MCOUNTEREN_ADDR 12'h306
`define ysyx_040991_CSR_MCOUNTINHIBIT_ADDR 12'h320
`define ysyx_040991_CSR_MSCRATCH_ADDR 12'h340
`define ysyx_040991_CSR_MEPC_ADDR 12'h341
`define ysyx_040991_CSR_MCAUSE_ADDR 12'h342
`define ysyx_040991_CSR_MTVAL_ADDR 12'h343
`define ysyx_040991_CSR_MIP_ADDR 12'h344
`define ysyx_040991_CSR_MCYCLE_ADDR 12'hB00
`define ysyx_040991_CSR_MHARTID_ADDR 12'hF14
`define ysyx_040991_PRIV_USER 2'b00
`define ysyx_040991_PRIV_SUPERVISOR 2'b11
`define ysyx_040991_PRIV_MACHINE 2'b11
`define ysyx_040991_IRQ_S_SOFT 4'd1
`define ysyx_040991_IRQ_M_SOFT 4'd3
`define ysyx_040991_IRQ_S_TIMER 4'd5
`define ysyx_040991_IRQ_M_TIMER 4'd7
`define ysyx_040991_IRQ_S_EXT 4'd9
`define ysyx_040991_IRQ_M_EXT 4'd11
`define ysyx_040991_MSTATUS_MIE 3
`define ysyx_040991_MSTATUS_MPIE 7
`define ysyx_040991_MSTATUS_MPP 12:11
`define ysyx_040991_MIP_MTIP 7
`define ysyx_040991_MIP_SD 63
`define ysyx_040991_EXCEPTION_INTERRUPT 2'b10
`define ysyx_040991_EXCEPTION_EXCEPTION 2'b01
`define ysyx_040991_EXCEPTION_ERET 2'b11
`define ysyx_040991_EXCEPTION_INST_ADDR_MISALIGNED 4'd0
`define ysyx_040991_EXCEPTION_INST_ACCESS_FAULT 4'd1
`define ysyx_040991_EXCEPTION_ILLEGAL_INST 4'd2
`define ysyx_040991_EXCEPTION_BREAKPOINT 4'd3
`define ysyx_040991_EXCEPTION_LOAD_ADDR_MISALIGNED 4'd4
`define ysyx_040991_EXCEPTION_LOAD_ACCESS_FAULT 4'd5
`define ysyx_040991_EXCEPTION_STORE_ADDR_MISALIGNED 4'd6
`define ysyx_040991_EXCEPTION_STORE_ACCESS_FAULT 4'd7
`define ysyx_040991_EXCEPTION_ECALL_U 4'd8
`define ysyx_040991_EXCEPTION_ECALL_S 4'd9
`define ysyx_040991_EXCEPTION_ECALL_M 4'd11
`define ysyx_040991_EXCEPTION_PAGE_FAULT_INST 4'd12
`define ysyx_040991_EXCEPTION_PAGE_FAULT_LOAD 4'd13
`define ysyx_040991_EXCEPTION_PAGE_FAULT_STORE 4'd14
// cache definitions
// cache ram size ysyx_040991_CACHE_LINE_BYTE_NUM * 2^ysyx_040991_CACHE_INDEX_WD * ysyx_040991_CACHE_WAY_NUM = ysyx_040991_CACHE_DATA_RAM_SIZE
`define ysyx_040991_CACHE_WAY_NUM 2
`define ysyx_040991_CACHE_DATA_RAM_SIZE 4096
`define ysyx_040991_CACHE_LINE_BYTE_NUM 32
`define ysyx_040991_CACHE_TAG_WD (32 - `ysyx_040991_CACHE_INDEX_WD - `ysyx_040991_CACHE_OFFSET_WD)
`define ysyx_040991_CACHE_INDEX_WD $clog2(`ysyx_040991_CACHE_DATA_RAM_SIZE / `ysyx_040991_CACHE_WAY_NUM / `ysyx_040991_CACHE_LINE_BYTE_NUM)
`define ysyx_040991_CACHE_OFFSET_WD $clog2(`ysyx_040991_CACHE_LINE_BYTE_NUM)
`define ysyx_040991_CACHE_LINE_WD `ysyx_040991_CACHE_LINE_BYTE_NUM * 8
`define ysyx_040991_CACHE_DATA_RAM_BANK_NUM (`ysyx_040991_CACHE_LINE_BYTE_NUM / 8)
`define ysyx_040991_CACHE_RAM_DEPTH 2**`ysyx_040991_CACHE_INDEX_WD
`define ysyx_040991_CACHE_OP_WRITE 1'b1
`define ysyx_040991_CACHE_OP_READ 1'b0
`define ysyx_040991_ICACHE_ARID 4'h0
`define ysyx_040991_DCACHE_ARID 4'h1
`define ysyx_040991_ICACHE_RID 4'h0
`define ysyx_040991_DCACHE_RID 4'h1
`define ysyx_040991_CACHE_SYNC_BUS_WD (`ysyx_040991_CACHE_WAY_NUM * (`ysyx_040991_CACHE_LINE_WD + `ysyx_040991_CACHE_TAG_WD + 1 + 1)) // 2*(256+21+1+1)
module ysyx_040991_adder3 (
input a,
input b,
input cin,
output cout,
output s
);
assign s = a ^ b ^ cin;
assign cout = (a & b) | (b & cin) | (a & cin);
endmodule
module ysyx_040991_adder #(
parameter WIDTH = 8
)(
input [WIDTH-1:0] a,
input [WIDTH-1:0] b,
output [WIDTH-1:0] y
);
assign y = a + b;
endmodule
module ysyx_040991_alu #(
parameter ysyx_040991_DATA_WIDTH = 64,
parameter ALU_WIDTH = 11
)(
input [ysyx_040991_DATA_WIDTH-1:0] alu_src1,
input [ysyx_040991_DATA_WIDTH-1:0] alu_src2,
input [ALU_WIDTH-1:0] alu_op,
input word_sel, // word instructions
output [ysyx_040991_DATA_WIDTH-1:0] alu_result
);
wire op_add;
wire op_sub;
wire op_slt;
wire op_sltu;
wire op_and;
wire op_or;
wire op_xor;
wire op_sll;
wire op_srl;
wire op_sra;
wire op_nop;
wire op_addw = alu_op[ 0] & word_sel;
wire op_subw = alu_op[ 1] & word_sel;
wire op_sllw = alu_op[ 8] & word_sel;
wire op_srlw = alu_op[ 9] & word_sel;
wire op_sraw = alu_op[10] & word_sel;
// control code decomposition
assign op_add = alu_op[ 0] & ~word_sel;
assign op_sub = alu_op[ 1] & ~word_sel;
assign op_slt = alu_op[ 2];
assign op_sltu = alu_op[ 3];
assign op_and = alu_op[ 4];
assign op_nop = alu_op[ 5];
assign op_or = alu_op[ 6];
assign op_xor = alu_op[ 7];
assign op_sll = alu_op[ 8] & ~word_sel;
assign op_srl = alu_op[ 9] & ~word_sel;
assign op_sra = alu_op[10] & ~word_sel;
wire [ysyx_040991_DATA_WIDTH-1:0] add_sub_result;
wire [ysyx_040991_DATA_WIDTH-1:0] slt_result;
wire [ysyx_040991_DATA_WIDTH-1:0] sltu_result;
wire [ysyx_040991_DATA_WIDTH-1:0] and_result;
wire [ysyx_040991_DATA_WIDTH-1:0] or_result;
wire [ysyx_040991_DATA_WIDTH-1:0] xor_result;
wire [ysyx_040991_DATA_WIDTH-1:0] nop_result;
wire [ysyx_040991_DATA_WIDTH-1:0] sll_result;
wire [ysyx_040991_DATA_WIDTH-1:0] srl_result;
wire [ysyx_040991_DATA_WIDTH-1:0] sra_result;
wire [ysyx_040991_DATA_WIDTH-1:0] addw_subw_result;
wire [ysyx_040991_DATA_WIDTH-1:0] sllw_result;
wire [ysyx_040991_DATA_WIDTH-1:0] srlw_result;
wire [ysyx_040991_DATA_WIDTH-1:0] sraw_result;
wire [ysyx_040991_DATA_WIDTH-1:0] adder_a;
wire [ysyx_040991_DATA_WIDTH-1:0] adder_b;
wire adder_cin;
wire [ysyx_040991_DATA_WIDTH-1:0] adder_result;
wire adder_cout;
assign adder_a = alu_src1;
assign adder_b = (op_sub | op_subw | op_slt | op_sltu) ? ~alu_src2 : alu_src2;
assign adder_cin = (op_sub | op_subw | op_slt | op_sltu) ? 1'b1 : 1'b0;
assign {adder_cout, adder_result} = adder_a + adder_b + {63'b0, adder_cin};
// add sub
assign add_sub_result = adder_result;
assign addw_subw_result = {{32{adder_result[31]}}, adder_result[31:0]};
// slt
assign slt_result[ysyx_040991_DATA_WIDTH-1:1] = 63'b0;
assign slt_result[0] = (alu_src1[ysyx_040991_DATA_WIDTH-1] & ~alu_src2[ysyx_040991_DATA_WIDTH-1])
| (~(alu_src1[ysyx_040991_DATA_WIDTH-1] ^ alu_src2[ysyx_040991_DATA_WIDTH-1]) & adder_result[ysyx_040991_DATA_WIDTH-1]);
// sltu
assign sltu_result[ysyx_040991_DATA_WIDTH-1:1] = 63'b0;
assign sltu_result[0] = ~adder_cout;
// bitwise operations
assign and_result = alu_src1 & alu_src2;
assign or_result = alu_src1 | alu_src2;
assign xor_result = alu_src1 ^ alu_src2;
assign nop_result = alu_src1;
// SLL result
assign sll_result = alu_src1 << alu_src2[5:0];
wire [31:0] sllw_temp = alu_src1[31:0] << alu_src2[4:0];
assign sllw_result = {{32{sllw_temp[31]}}, sllw_temp[31:0]};
// SRL result
assign srl_result = alu_src1 >> alu_src2[5:0];
wire [31:0] srlw_temp = alu_src1[31:0] >> alu_src2[4:0];
assign srlw_result = {{32{srlw_temp[31]}}, srlw_temp};
// SRA result
assign sra_result = ($signed(alu_src1)) >>> alu_src2[5:0];
wire [31:0] sraw_temp = ($signed(alu_src1[31:0])) >>> alu_src2[4:0];
assign sraw_result = {{32{sraw_temp[31]}}, sraw_temp};
// final result mux
assign alu_result = ({64{op_add|op_sub }} & add_sub_result)
| ({64{op_addw|op_subw}} & addw_subw_result)
| ({64{op_slt }} & slt_result)
| ({64{op_sltu }} & sltu_result)
| ({64{op_and }} & and_result)
| ({64{op_or }} & or_result)
| ({64{op_xor }} & xor_result)
| ({64{op_nop }} & nop_result)
| ({64{op_sll }} & sll_result)
| ({64{op_sllw }} & sllw_result)
| ({64{op_srl }} & srl_result)
| ({64{op_srlw }} & srlw_result)
| ({64{op_sra }} & sra_result)
| ({64{op_sraw }} & sraw_result);
endmodule
module ysyx_040991_axi_bridge #(
// Thread ID Width
parameter integer C_M_AXI_ID_WIDTH = 4,
// Width of Address Bus
parameter integer C_M_AXI_ADDR_WIDTH = 32,
// Width of Data Bus
parameter integer C_M_AXI_ysyx_040991_DATA_WIDTH = 64,
// Width of User Write Address Bus
parameter integer C_M_AXI_AWUSER_WIDTH = 1,
// Width of User Read Address Bus
parameter integer C_M_AXI_ARUSER_WIDTH = 1,
// Width of User Write Data Bus
parameter integer C_M_AXI_WUSER_WIDTH = 1,
// Width of User Read Data Bus
parameter integer C_M_AXI_RUSER_WIDTH = 1,
// Width of User Response Bus
parameter integer C_M_AXI_BUSER_WIDTH = 1
)(
input M_AXI_ACLK,
input M_AXI_ARESETN,
// icache read inputs
input icache_rd_req,
input [3:0] icache_rd_type, // 4'b1000: 8bit; 4'b0100: 16bit; 4'b0010: 32bit; 4'b0001: 64bit; 4'b0000: cache line(256bit)
input [31:0] icache_rd_addr, // init burst address
output reg icache_rd_rdy,
// return data
output reg icache_ret_valid,
output reg icache_ret_last,
output reg [63:0] icache_ret_data,
// dcache read inputs
input dcache_rd_req,
input [3:0] dcache_rd_type, // 4'b1000: 8bit; 4'b0100: 16bit; 4'b0010: 32bit; 4'b0001: 64bit; 4'b0000: cache line(256bit)
input [31:0] dcache_rd_addr, // init burst address
output reg dcache_rd_rdy,
// return data
output reg dcache_ret_valid,
output reg dcache_ret_last,
output reg [63:0] dcache_ret_data,
// write request
input dcache_wr_req,
input [3:0] dcache_wr_type, // 4'b1000: 8bit; 4'b0100: 16bit; 4'b0010: 32bit; 4'b0001: 64bit; 4'b0000: cache line(256bit)
input [31:0] dcache_wr_addr, // init burst address
input [7:0] dcache_wr_wstrb, // only valid when wr_type is 4'b0000 & 4'b0001 & 4'b0010 & 4'b0100
input [255:0] dcache_wr_data,
output dcache_wr_rdy,
// axi4 ports
output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_AWID,
output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_AWADDR,
output wire [7 : 0] M_AXI_AWLEN,
output wire [2 : 0] M_AXI_AWSIZE,
output wire [1 : 0] M_AXI_AWBURST,
output wire M_AXI_AWLOCK,
output wire [3 : 0] M_AXI_AWCACHE,
output wire [2 : 0] M_AXI_AWPROT,
output wire [3 : 0] M_AXI_AWQOS,
output wire [3 : 0] M_AXI_AWREGION,
output wire [C_M_AXI_AWUSER_WIDTH-1 : 0] M_AXI_AWUSER,
output wire M_AXI_AWVALID,
input wire M_AXI_AWREADY,
output wire [C_M_AXI_ysyx_040991_DATA_WIDTH-1 : 0] M_AXI_WDATA,
output wire [C_M_AXI_ysyx_040991_DATA_WIDTH/8-1 : 0] M_AXI_WSTRB,
output wire M_AXI_WLAST,
output wire [C_M_AXI_WUSER_WIDTH-1 : 0] M_AXI_WUSER,
output wire M_AXI_WVALID,
input wire M_AXI_WREADY,
input wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_BID,
input wire [1 : 0] M_AXI_BRESP,
input wire [C_M_AXI_BUSER_WIDTH-1 : 0] M_AXI_BUSER,
input wire M_AXI_BVALID,
output wire M_AXI_BREADY,
output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_ARID,
output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_ARADDR,
output wire [7 : 0] M_AXI_ARLEN,
output wire [2 : 0] M_AXI_ARSIZE,
output wire [1 : 0] M_AXI_ARBURST,
output wire M_AXI_ARLOCK,
output wire [3 : 0] M_AXI_ARCACHE,
output wire [2 : 0] M_AXI_ARPROT,
output wire [3 : 0] M_AXI_ARQOS,
output wire [3 : 0] M_AXI_ARREGION,
output wire [C_M_AXI_ARUSER_WIDTH-1 : 0] M_AXI_ARUSER,
output wire M_AXI_ARVALID,
input wire M_AXI_ARREADY,
input wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_RID,
input wire [C_M_AXI_ysyx_040991_DATA_WIDTH-1 : 0] M_AXI_RDATA,
input wire [1 : 0] M_AXI_RRESP,
input wire M_AXI_RLAST,
input wire [C_M_AXI_RUSER_WIDTH-1 : 0] M_AXI_RUSER,
input wire M_AXI_RVALID,
output wire M_AXI_RREADY
);
function integer clogb2 (input integer bit_depth);
begin
for(clogb2=0; bit_depth>0; clogb2=clogb2+1)
bit_depth = bit_depth >> 1;
end
endfunction
reg [C_M_AXI_ADDR_WIDTH-1 : 0] axi_awaddr;
reg axi_awvalid;
reg [7 : 0] axi_awlen;
reg [2 : 0] axi_awsize;
reg [C_M_AXI_ysyx_040991_DATA_WIDTH-1 : 0] axi_wdata;
reg axi_wlast;
reg axi_wvalid;
reg [C_M_AXI_ysyx_040991_DATA_WIDTH/8-1 : 0] axi_wstrb;
reg axi_bready;
reg [C_M_AXI_ADDR_WIDTH-1 : 0] axi_araddr;
reg axi_arvalid;
reg [3 : 0] axi_arid;
reg [7 : 0] axi_arlen;
reg [2 : 0] axi_arsize;
reg axi_rready;
//write beat count in a burst
reg [31 : 0] write_index;
wire wnext;
wire [7:0] C_M_AXI_BURST_LEN;
assign C_M_AXI_BURST_LEN = ({8{dcache_wr_type == 4'b0000}} & 8'h4)
| ({8{dcache_wr_type == 4'b0001}} & 8'h1)
| ({8{dcache_wr_type == 4'b0010}} & 8'h1)
| ({8{dcache_wr_type == 4'b0100}} & 8'h1)
| ({8{dcache_wr_type == 4'b1000}} & 8'h1);
assign M_AXI_AWID = 'b0;
assign M_AXI_AWADDR = axi_awaddr;
assign M_AXI_AWLEN = axi_awlen;
assign M_AXI_AWSIZE = axi_awsize;
assign M_AXI_AWBURST = 2'b01;
assign M_AXI_AWLOCK = 1'b0;
assign M_AXI_AWCACHE = 4'b0000; // non bufferable
assign M_AXI_AWPROT = 3'h0;
assign M_AXI_AWQOS = 4'h0;
assign M_AXI_AWREGION = 4'h0;
assign M_AXI_AWUSER = 'b1;
assign M_AXI_AWVALID = axi_awvalid;
//Write Data(W)
assign M_AXI_WDATA = axi_wdata;
assign M_AXI_WSTRB = axi_wstrb;
assign M_AXI_WLAST = axi_wlast;
assign M_AXI_WUSER = 'b0;
assign M_AXI_WVALID = axi_wvalid;
//Write Response (B)
assign M_AXI_BREADY = axi_bready;
//Read Address (AR)
assign M_AXI_ARADDR = axi_araddr;
assign M_AXI_ARLEN = axi_arlen;
assign M_AXI_ARSIZE = axi_arsize;
assign M_AXI_ARBURST = 2'b01;
assign M_AXI_ARLOCK = 1'b0;
assign M_AXI_ARCACHE = 4'b0000; // non bufferable
assign M_AXI_ARPROT = 3'h0;
assign M_AXI_ARQOS = 4'h0;
assign M_AXI_ARREGION = 4'h0;
assign M_AXI_ARUSER = 'b1;
assign M_AXI_ARVALID = axi_arvalid;
assign M_AXI_ARID = axi_arid;
//Read and Read Response (R)
assign M_AXI_RREADY = axi_rready;
assign wnext = M_AXI_WREADY & axi_wvalid;
// write data buffer
reg [255:0] wr_data_buffer;
reg [31:0] wr_burst_len;
always @(posedge M_AXI_ACLK) begin
if (M_AXI_ARESETN == 0) begin
wr_data_buffer <= 256'b0;
end
else if (dcache_wr_req) begin
wr_data_buffer <= dcache_wr_data;
end
else begin
wr_data_buffer <= wr_data_buffer;
end
end
always @(posedge M_AXI_ACLK) begin
if (M_AXI_ARESETN == 0) begin
wr_burst_len <= 32'b0;
end
else if (dcache_wr_req) begin
wr_burst_len <= {24'b0, C_M_AXI_BURST_LEN};
end
else begin
wr_burst_len <= wr_burst_len;
end
end
//--------------------
//Write Address Channel
//--------------------
reg [2:0] aw_curr_state, aw_next_state;
localparam AW_IDLE = 3'b001;
localparam AW_WAIT = 3'b010;
localparam AW_ACTIVE = 3'b100;
assign dcache_wr_rdy = aw_curr_state == AW_WAIT || aw_curr_state == AW_IDLE;
always @(posedge M_AXI_ACLK) begin
if (M_AXI_ARESETN == 0) begin
aw_curr_state <= AW_IDLE;
end
else begin
aw_curr_state <= aw_next_state;
end
end
always @(*) begin
case (aw_curr_state)
AW_IDLE: begin
aw_next_state = AW_WAIT;
end
AW_WAIT: begin
if (dcache_wr_req) begin
aw_next_state = AW_ACTIVE;
end
else begin
aw_next_state = AW_WAIT;
end
end
AW_ACTIVE: begin
if (M_AXI_BVALID && M_AXI_BREADY) begin
aw_next_state = AW_WAIT;
end
else begin
aw_next_state = AW_ACTIVE;
end
end
default: begin
aw_next_state = AW_IDLE;
end
endcase
end
always @(posedge M_AXI_ACLK) begin
if (aw_next_state == AW_IDLE || aw_next_state == AW_WAIT) begin
axi_awvalid <= 1'b0;
end
else if (aw_curr_state == AW_WAIT && dcache_wr_req) begin
axi_awvalid <= 1'b1;
end
else if (M_AXI_AWREADY) begin
axi_awvalid <= 1'b0;
end
else begin
axi_awvalid <= axi_awvalid;
end
end
always @(posedge M_AXI_ACLK) begin
if (aw_next_state == AW_IDLE || aw_next_state == AW_WAIT) begin
axi_awaddr <= 'b0;
end
else if (aw_curr_state == AW_WAIT && dcache_wr_req) begin
axi_awaddr <= dcache_wr_addr;
end
else begin
axi_awaddr <= axi_awaddr;
end
end
always @(posedge M_AXI_ACLK) begin
if (aw_next_state == AW_IDLE || aw_next_state == AW_WAIT) begin
axi_awlen <= 'b0;
end
else if (aw_curr_state == AW_WAIT && dcache_wr_req) begin
axi_awlen <= C_M_AXI_BURST_LEN - 8'b1;
end
else begin
axi_awlen <= axi_awlen;
end
end
always @(posedge M_AXI_ACLK) begin
if (aw_next_state == AW_IDLE || aw_next_state == AW_WAIT) begin
axi_awsize <= 'b0;
end
else if (aw_curr_state == AW_WAIT && dcache_wr_req) begin
axi_awsize <= ({3{dcache_wr_type == 4'b0000}} & 3'b011)
| ({3{dcache_wr_type == 4'b0001}} & 3'b011)
| ({3{dcache_wr_type == 4'b0010}} & 3'b010)
| ({3{dcache_wr_type == 4'b0100}} & 3'b001)
| ({3{dcache_wr_type == 4'b1000}} & 3'b000);
end
else begin
axi_awsize <= axi_awsize;
end
end
//--------------------
//Write Data Channel
//--------------------
always @(posedge M_AXI_ACLK) begin
if (aw_next_state == AW_IDLE || aw_next_state == AW_WAIT) begin
axi_wvalid <= 1'b0;
end
else if (aw_curr_state == AW_WAIT) begin
axi_wvalid <= 1'b1;
end
else begin
axi_wvalid <= axi_wvalid;
end
end
always @(posedge M_AXI_ACLK) begin
if (aw_next_state == AW_IDLE || aw_next_state == AW_WAIT) begin
axi_wlast <= 1'b0;
end
else if (aw_curr_state == AW_ACTIVE && (wnext && write_index == wr_burst_len-2 || wr_burst_len == 1)) begin
axi_wlast <= 1'b1;
end
else if (wnext) begin
axi_wlast <= 1'b0;
end
else begin
axi_wlast <= axi_wlast;
end
end
always @(posedge M_AXI_ACLK) begin
if (aw_next_state == AW_IDLE || aw_next_state == AW_WAIT) begin
write_index <= 'b0;
end
else if (wnext && (write_index != wr_burst_len-1)) begin
write_index <= write_index + 1;
end
else begin
write_index <= write_index;
end
end
always @(posedge M_AXI_ACLK) begin
if (aw_next_state == AW_IDLE || aw_next_state == AW_WAIT) begin
axi_wdata <= 64'b0;
end
else if (aw_curr_state == AW_WAIT && dcache_wr_req) begin
axi_wdata <= dcache_wr_data[0 +: 64];
end
else if (aw_curr_state == AW_ACTIVE && wnext && write_index != wr_burst_len) begin
axi_wdata <= wr_data_buffer[(write_index+1)*64 +: 64];
end
else begin
axi_wdata <= axi_wdata;
end
end
always @(posedge M_AXI_ACLK) begin
if (aw_next_state == AW_IDLE || aw_next_state == AW_WAIT) begin
axi_wstrb <= 8'b0;
end
else if (aw_curr_state == AW_WAIT && dcache_wr_req) begin
axi_wstrb <= dcache_wr_wstrb;
end
else if (aw_curr_state == AW_ACTIVE && wnext && write_index != wr_burst_len) begin
axi_wstrb <= 8'hff;
end
else begin
axi_wstrb <= axi_wstrb;
end
end
//----------------------------
//Write Response (B) Channel
//----------------------------
reg [1:0] b_curr_state, b_next_state;
localparam B_IDLE = 2'b01;
localparam B_WAIT = 2'b10;
always @(posedge M_AXI_ACLK) begin
if (M_AXI_ARESETN == 0) begin
b_curr_state <= B_IDLE;
end
else begin
b_curr_state <= b_next_state;
end
end
always @(*) begin
case (b_curr_state)
B_IDLE: begin
if (dcache_wr_req) begin
b_next_state = B_WAIT;
end
else begin
b_next_state = B_IDLE;
end
end
B_WAIT: begin
if (M_AXI_BVALID) begin
b_next_state = B_IDLE;
end
else begin
b_next_state = B_WAIT;
end
end
default: begin
b_next_state = B_IDLE;
end
endcase
end
always @(*) begin
if (b_curr_state == B_WAIT) begin
axi_bready = 1'b1;
end
else begin
axi_bready = 1'b0;
end
end
//----------------------------
//Read Address Channel
//----------------------------
reg [2:0] ar_curr_state, ar_next_state;
localparam AR_IDLE = 3'b001;
localparam AR_ICACHE = 3'b010;
localparam AR_DCACHE = 3'b100;
always @(posedge M_AXI_ACLK) begin
if (M_AXI_ARESETN == 0) begin
ar_curr_state <= AR_IDLE;
end
else begin
ar_curr_state <= ar_next_state;
end
end
wire ar_stall;
assign ar_stall = b_curr_state == B_WAIT;
wire r_icache_complete, r_dcache_complete;
always @(*) begin
case (ar_curr_state)
AR_IDLE: begin
if (dcache_rd_req && !ar_stall) begin
ar_next_state = AR_DCACHE;
end
else if (icache_rd_req && !ar_stall) begin
ar_next_state = AR_ICACHE;
end
else begin
ar_next_state = AR_IDLE;
end
end
AR_DCACHE: begin
if (r_dcache_complete) begin
if (dcache_rd_req) begin
ar_next_state = AR_DCACHE;
end
else if (icache_rd_req) begin
ar_next_state = AR_ICACHE;
end
else begin
ar_next_state = AR_IDLE;
end
end
else begin
ar_next_state = AR_DCACHE;
end
end
AR_ICACHE: begin
if (r_icache_complete) begin
if (dcache_rd_req) begin
ar_next_state = AR_DCACHE;
end
else if (icache_rd_req) begin
ar_next_state = AR_ICACHE;
end
else begin
ar_next_state = AR_IDLE;
end
end
else begin
ar_next_state = AR_ICACHE;
end
end
default: begin
ar_next_state = AR_IDLE;
end
endcase
end
always @(*) begin
case (ar_curr_state)
AR_IDLE: begin
axi_arid = 4'b0;
axi_arvalid = 1'b0;
axi_araddr = 32'b0;
axi_arlen = 8'b0;
axi_arsize = 3'b0;
dcache_rd_rdy = 1'b0;
icache_rd_rdy = 1'b0;
end
AR_DCACHE: begin
axi_arid = dcache_rd_req ? 4'b1 : 'b0;
axi_arvalid = dcache_rd_req ? 1'b1 : 'b0;
axi_araddr = dcache_rd_req ? dcache_rd_addr : 'b0;
axi_arlen = dcache_rd_req ? ({8{dcache_rd_type == 4'b0000}} & 8'h3)
| ({8{dcache_rd_type == 4'b0001}} & 8'h0)
| ({8{dcache_rd_type == 4'b0010}} & 8'h0)
| ({8{dcache_rd_type == 4'b0100}} & 8'h0)
| ({8{dcache_rd_type == 4'b1000}} & 8'h0)
: 'b0;
axi_arsize = dcache_rd_req ? ({3{dcache_rd_type == 4'b0000}} & 3'b011)
| ({3{dcache_rd_type == 4'b0001}} & 3'b011)
| ({3{dcache_rd_type == 4'b0010}} & 3'b010)
| ({3{dcache_rd_type == 4'b0100}} & 3'b001)
| ({3{dcache_rd_type == 4'b1000}} & 3'b000)
: 'b0;
dcache_rd_rdy = M_AXI_ARREADY;
icache_rd_rdy = 1'b0;
end
AR_ICACHE: begin
axi_arid = icache_rd_req ? 4'b0 : 'b0;
axi_arvalid = icache_rd_req ? 1'b1 : 'b0;
axi_araddr = icache_rd_req ? icache_rd_addr : 'b0;
axi_arlen = icache_rd_req ? ({8{icache_rd_type == 4'b0000}} & 8'h3)
| ({8{icache_rd_type == 4'b0001}} & 8'h0)
| ({8{icache_rd_type == 4'b0010}} & 8'h0)
| ({8{icache_rd_type == 4'b0100}} & 8'h0)
| ({8{icache_rd_type == 4'b1000}} & 8'h0)
: 'b0;
axi_arsize = icache_rd_req ? ({3{icache_rd_type == 4'b0000}} & 3'b011)
| ({3{icache_rd_type == 4'b0001}} & 3'b011)
| ({3{icache_rd_type == 4'b0010}} & 3'b010)
| ({3{icache_rd_type == 4'b0100}} & 3'b001)
| ({3{icache_rd_type == 4'b1000}} & 3'b000)
: 'b0;
dcache_rd_rdy = 1'b0;
icache_rd_rdy = M_AXI_ARREADY;
end
default: begin
axi_arid = 4'b0;
axi_arvalid = 1'b0;
axi_araddr = 32'b0;
axi_arlen = 8'b0;
axi_arsize = 3'b0;
dcache_rd_rdy = 1'b0;
icache_rd_rdy = 1'b0;
end
endcase
end
//--------------------------------
//Read Data (and Response) Channel
//--------------------------------
assign r_icache_complete = M_AXI_RVALID && M_AXI_RLAST && axi_rready && M_AXI_RID == `ysyx_040991_ICACHE_RID;
assign r_dcache_complete = M_AXI_RVALID && M_AXI_RLAST && axi_rready && M_AXI_RID == `ysyx_040991_DCACHE_RID;
always @(*) begin
if (ar_curr_state != AR_IDLE) begin
axi_rready = 1'b1;
end
else begin
axi_rready = 1'b0;
end
end
reg icache_ret_valid_next;
reg icache_ret_last_next;
reg [63:0] icache_ret_data_next;
reg dcache_ret_valid_next;
reg dcache_ret_last_next;
reg [63:0] dcache_ret_data_next;
always @(*) begin
case (ar_curr_state)
AR_IDLE: begin
icache_ret_valid_next = 1'b0;
icache_ret_last_next = 1'b0;
icache_ret_data_next = 64'b0;
dcache_ret_valid_next = 1'b0;
dcache_ret_last_next = 1'b0;
dcache_ret_data_next = 64'b0;
end
AR_ICACHE: begin
icache_ret_valid_next = (M_AXI_RID == `ysyx_040991_ICACHE_RID) ? M_AXI_RVALID : 1'b0;
icache_ret_last_next = (M_AXI_RID == `ysyx_040991_ICACHE_RID) ? M_AXI_RLAST : 1'b0;
icache_ret_data_next = (M_AXI_RID == `ysyx_040991_ICACHE_RID) ? M_AXI_RDATA : 64'b0;
dcache_ret_valid_next = 1'b0;
dcache_ret_last_next = 1'b0;
dcache_ret_data_next = 64'b0;
end
AR_DCACHE: begin
icache_ret_valid_next = 1'b0;
icache_ret_last_next = 1'b0;
icache_ret_data_next = 64'b0;
dcache_ret_valid_next = (M_AXI_RID == `ysyx_040991_DCACHE_RID) ? M_AXI_RVALID : 1'b0;
dcache_ret_last_next = (M_AXI_RID == `ysyx_040991_DCACHE_RID) ? M_AXI_RLAST : 1'b0;
dcache_ret_data_next = (M_AXI_RID == `ysyx_040991_DCACHE_RID) ? M_AXI_RDATA : 64'b0;
end
default: begin
icache_ret_valid_next = 1'b0;
icache_ret_last_next = 1'b0;
icache_ret_data_next = 64'b0;
dcache_ret_valid_next = 1'b0;
dcache_ret_last_next = 1'b0;
dcache_ret_data_next = 64'b0;
end
endcase
end
always @(posedge M_AXI_ACLK) begin
if (!M_AXI_ARESETN) begin
icache_ret_valid <= 1'b0;
icache_ret_last <= 1'b0;
icache_ret_data <= 64'b0;
dcache_ret_valid <= 1'b0;
dcache_ret_last <= 1'b0;
dcache_ret_data <= 64'b0;
end
else begin
icache_ret_valid <= icache_ret_valid_next;
icache_ret_last <= icache_ret_last_next;
icache_ret_data <= icache_ret_data_next;
dcache_ret_valid <= dcache_ret_valid_next;
dcache_ret_last <= dcache_ret_last_next;
dcache_ret_data <= dcache_ret_data_next;
end
end
endmodule
module ysyx_040991_axi_clint #
(
// Width of data bus in bits
parameter ysyx_040991_DATA_WIDTH = 64,
// Width of address bus in bits
parameter ADDR_WIDTH = 32,
// Width of wstrb (width of data bus in words)
parameter STRB_WIDTH = (ysyx_040991_DATA_WIDTH/8),
// Width of ID signal
parameter ID_WIDTH = 4
)(
input wire clk,
input wire rst,
input wire [ID_WIDTH-1:0] s_axi_awid,
input wire [ADDR_WIDTH-1:0] s_axi_awaddr,
input wire [7:0] s_axi_awlen,
input wire [2:0] s_axi_awsize,
input wire [1:0] s_axi_awburst,
input wire s_axi_awlock,
input wire [3:0] s_axi_awcache,
input wire [2:0] s_axi_awprot,
input wire [3:0] s_axi_awqos,
input wire [3:0] s_axi_awregion,
input wire [1-1:0] s_axi_awuser,
input wire s_axi_awvalid,
output wire s_axi_awready,
input wire [ysyx_040991_DATA_WIDTH-1:0] s_axi_wdata,
input wire [STRB_WIDTH-1:0] s_axi_wstrb,
input wire s_axi_wlast,
input wire [1-1:0] s_axi_wuser,
input wire s_axi_wvalid,
output wire s_axi_wready,
output wire [ID_WIDTH-1:0] s_axi_bid,
output wire [1:0] s_axi_bresp,
output wire [1-1:0] s_axi_buser,
output wire s_axi_bvalid,
input wire s_axi_bready,
input wire [ID_WIDTH-1:0] s_axi_arid,
input wire [ADDR_WIDTH-1:0] s_axi_araddr,
input wire [7:0] s_axi_arlen,
input wire [2:0] s_axi_arsize,
input wire [1:0] s_axi_arburst,
input wire s_axi_arlock,
input wire [3:0] s_axi_arcache,
input wire [2:0] s_axi_arprot,
input wire [3:0] s_axi_arqos,
input wire [3:0] s_axi_arregion,
input wire [1-1:0] s_axi_aruser,
input wire s_axi_arvalid,
output wire s_axi_arready,
output wire [ID_WIDTH-1:0] s_axi_rid,
output wire [ysyx_040991_DATA_WIDTH-1:0] s_axi_rdata,
output wire [1:0] s_axi_rresp,
output wire s_axi_rlast,
output wire [1-1:0] s_axi_ruser,
output wire s_axi_rvalid,
input wire s_axi_rready,
output wire timer_interrupt
);
parameter VALID_ADDR_WIDTH = ADDR_WIDTH - $clog2(STRB_WIDTH);
parameter WORD_WIDTH = STRB_WIDTH;
parameter WORD_SIZE = ysyx_040991_DATA_WIDTH/WORD_WIDTH;
localparam [0:0]
READ_STATE_IDLE = 1'd0,
READ_STATE_BURST = 1'd1;
reg [0:0] read_state_reg, read_state_next;
localparam [1:0]
WRITE_STATE_IDLE = 2'd0,
WRITE_STATE_BURST = 2'd1,
WRITE_STATE_RESP = 2'd2;
reg [1:0] write_state_reg, write_state_next;
reg mem_wr_en;
reg mem_rd_en;
reg [ID_WIDTH-1:0] read_id_reg, read_id_next;
reg [ADDR_WIDTH-1:0] read_addr_reg, read_addr_next;
reg [7:0] read_count_reg, read_count_next;
reg [2:0] read_size_reg, read_size_next;
reg [1:0] read_burst_reg, read_burst_next;
reg [ID_WIDTH-1:0] write_id_reg, write_id_next;
reg [ADDR_WIDTH-1:0] write_addr_reg, write_addr_next;
reg [7:0] write_count_reg, write_count_next;
reg [2:0] write_size_reg, write_size_next;
reg [1:0] write_burst_reg, write_burst_next;
reg s_axi_awready_reg, s_axi_awready_next;
reg s_axi_wready_reg, s_axi_wready_next;
reg [ID_WIDTH-1:0] s_axi_bid_reg, s_axi_bid_next;
reg s_axi_bvalid_reg, s_axi_bvalid_next;
reg s_axi_arready_reg, s_axi_arready_next;
reg [ID_WIDTH-1:0] s_axi_rid_reg, s_axi_rid_next;
reg [ysyx_040991_DATA_WIDTH-1:0] s_axi_rdata_reg;
reg s_axi_rlast_reg, s_axi_rlast_next;
reg s_axi_rvalid_reg, s_axi_rvalid_next;
wire [2:0] unused_3 [0:1];
wire [VALID_ADDR_WIDTH-1:0] read_addr_valid;
assign {unused_3[0], read_addr_valid}= read_addr_reg >> (ADDR_WIDTH - VALID_ADDR_WIDTH);
wire [VALID_ADDR_WIDTH-1:0] write_addr_valid;
assign {unused_3[1], write_addr_valid} = write_addr_reg >> (ADDR_WIDTH - VALID_ADDR_WIDTH);
assign s_axi_awready = s_axi_awready_reg;
assign s_axi_wready = s_axi_wready_reg;
assign s_axi_bid = s_axi_bid_reg;
assign s_axi_bresp = 2'b00;
assign s_axi_bvalid = s_axi_bvalid_reg;
assign s_axi_arready = s_axi_arready_reg;
assign s_axi_rid = s_axi_rid_reg;
assign s_axi_rdata = s_axi_rdata_reg;
assign s_axi_rresp = 2'b00;
assign s_axi_rlast = s_axi_rlast_reg;
assign s_axi_rvalid = s_axi_rvalid_reg;
integer i;
reg [ysyx_040991_DATA_WIDTH-1:0] csr_msip;
reg [ysyx_040991_DATA_WIDTH-1:0] csr_mtimecmp;
reg [ysyx_040991_DATA_WIDTH-1:0] csr_mtime;
localparam BASE_ADDR = 32'h0200_0000;
localparam MSIP_OFFSET = 32'h0;
localparam MTIMECMP_OFFSET = 32'h4000;
localparam MTIME_OFFSET = 32'hBFF8;
localparam MSIP_ADDR = BASE_ADDR + MSIP_OFFSET;
localparam MTIMECMP_ADDR = BASE_ADDR + MTIMECMP_OFFSET;
localparam MTIME_ADDR = BASE_ADDR + MTIME_OFFSET;
assign timer_interrupt = (csr_mtime > csr_mtimecmp);
always @(posedge clk) begin
if (rst) begin
csr_mtime <= 64'b0;
end
else begin
csr_mtime <= csr_mtime + 1;
end
end
wire [31:0] clog2_strb_width;
assign clog2_strb_width = $clog2(STRB_WIDTH);
always @(*) begin
write_state_next = WRITE_STATE_IDLE;
mem_wr_en = 1'b0;
write_id_next = write_id_reg;
write_addr_next = write_addr_reg;
write_count_next = write_count_reg;
write_size_next = write_size_reg;
write_burst_next = write_burst_reg;
s_axi_awready_next = 1'b0;
s_axi_wready_next = 1'b0;
s_axi_bid_next = s_axi_bid_reg;
s_axi_bvalid_next = s_axi_bvalid_reg && !s_axi_bready;
case (write_state_reg)
WRITE_STATE_IDLE: begin
s_axi_awready_next = 1'b1;
if (s_axi_awready && s_axi_awvalid) begin
write_id_next = s_axi_awid;
write_addr_next = s_axi_awaddr;
write_count_next = s_axi_awlen;
write_size_next = s_axi_awsize < clog2_strb_width[2:0] ? s_axi_awsize : clog2_strb_width[2:0];
write_burst_next = s_axi_awburst;
s_axi_awready_next = 1'b0;
s_axi_wready_next = 1'b1;
write_state_next = WRITE_STATE_BURST;
end else begin
write_state_next = WRITE_STATE_IDLE;
end
end
WRITE_STATE_BURST: begin
s_axi_wready_next = 1'b1;
if (s_axi_wready && s_axi_wvalid) begin
mem_wr_en = 1'b1;
if (write_burst_reg != 2'b00) begin
write_addr_next = write_addr_reg + (1 << write_size_reg);
end
write_count_next = write_count_reg - 1;
if (write_count_reg > 0) begin
write_state_next = WRITE_STATE_BURST;
end else begin
s_axi_wready_next = 1'b0;
if (s_axi_bready || !s_axi_bvalid) begin
s_axi_bid_next = write_id_reg;
s_axi_bvalid_next = 1'b1;
s_axi_awready_next = 1'b1;
write_state_next = WRITE_STATE_IDLE;
end else begin
write_state_next = WRITE_STATE_RESP;
end
end
end else begin
write_state_next = WRITE_STATE_BURST;
end
end
WRITE_STATE_RESP: begin
if (s_axi_bready || !s_axi_bvalid) begin
s_axi_bid_next = write_id_reg;
s_axi_bvalid_next = 1'b1;
s_axi_awready_next = 1'b1;
write_state_next = WRITE_STATE_IDLE;
end else begin
write_state_next = WRITE_STATE_RESP;
end
end
default: begin
write_state_next = WRITE_STATE_IDLE;
end
endcase
end
always @(posedge clk) begin
if (rst) begin
write_state_reg <= WRITE_STATE_IDLE;
s_axi_bid_reg <= {ID_WIDTH{1'b0}};
s_axi_awready_reg <= 1'b0;
s_axi_wready_reg <= 1'b0;
s_axi_bvalid_reg <= 1'b0;
csr_mtimecmp <= 64'b0;
csr_msip <= 64'b0;
write_id_reg <= {ID_WIDTH{1'b0}};
write_addr_reg <= {ADDR_WIDTH{1'b0}};
write_count_reg <= 8'd0;
write_size_reg <= 3'd0;
write_burst_reg <= 2'd0;
end
else begin
write_state_reg <= write_state_next;
write_id_reg <= write_id_next;
write_addr_reg <= write_addr_next;
write_count_reg <= write_count_next;
write_size_reg <= write_size_next;
write_burst_reg <= write_burst_next;
s_axi_awready_reg <= s_axi_awready_next;
s_axi_wready_reg <= s_axi_wready_next;
s_axi_bid_reg <= s_axi_bid_next;
s_axi_bvalid_reg <= s_axi_bvalid_next;
for (i = 0; i < WORD_WIDTH; i = i + 1) begin
if (mem_wr_en & s_axi_wstrb[i]) begin
case({write_addr_valid, 3'b0})
MSIP_ADDR: begin
csr_msip[WORD_SIZE*i +: WORD_SIZE] <= s_axi_wdata[WORD_SIZE*i +: WORD_SIZE];
end
MTIMECMP_ADDR: begin
csr_mtimecmp[WORD_SIZE*i +: WORD_SIZE] <= s_axi_wdata[WORD_SIZE*i +: WORD_SIZE];
end
endcase
end
end
end
end
always @(*) begin
read_state_next = READ_STATE_IDLE;
mem_rd_en = 1'b0;
s_axi_rid_next = s_axi_rid_reg;
s_axi_rlast_next = s_axi_rlast_reg;
s_axi_rvalid_next = s_axi_rvalid_reg && !s_axi_rready;
read_id_next = read_id_reg;
read_addr_next = read_addr_reg;
read_count_next = read_count_reg;
read_size_next = read_size_reg;
read_burst_next = read_burst_reg;
s_axi_arready_next = 1'b0;
case (read_state_reg)
READ_STATE_IDLE: begin
s_axi_arready_next = 1'b1;
if (s_axi_arready && s_axi_arvalid) begin
read_id_next = s_axi_arid;
read_addr_next = s_axi_araddr;
read_count_next = s_axi_arlen;
read_size_next = s_axi_arsize < clog2_strb_width[2:0] ? s_axi_arsize : clog2_strb_width[2:0];
read_burst_next = s_axi_arburst;
s_axi_arready_next = 1'b0;
read_state_next = READ_STATE_BURST;
end else begin
read_state_next = READ_STATE_IDLE;
end
end
READ_STATE_BURST: begin
if (s_axi_rready || !s_axi_rvalid_reg) begin
mem_rd_en = 1'b1;
s_axi_rvalid_next = 1'b1;
s_axi_rid_next = read_id_reg;
s_axi_rlast_next = read_count_reg == 0;
if (read_burst_reg != 2'b00) begin
read_addr_next = read_addr_reg + (1 << read_size_reg);
end
read_count_next = read_count_reg - 1;
if (read_count_reg > 0) begin
read_state_next = READ_STATE_BURST;
end else begin
s_axi_arready_next = 1'b1;
read_state_next = READ_STATE_IDLE;
end
end else begin
read_state_next = READ_STATE_BURST;
end
end
endcase
end
always @(posedge clk) begin
if (rst) begin
read_state_reg <= READ_STATE_IDLE;
s_axi_rlast_reg <= 1'b0;
s_axi_rdata_reg <= {ysyx_040991_DATA_WIDTH{1'b0}};
s_axi_rid_reg <= {ID_WIDTH{1'b0}};
s_axi_arready_reg <= 1'b0;
s_axi_rvalid_reg <= 1'b0;
read_id_reg <= {ID_WIDTH{1'b0}};
read_addr_reg <= {ADDR_WIDTH{1'b0}};
read_count_reg <= 8'd0;
read_size_reg <= 3'd0;
read_burst_reg <= 2'd0;
end
else begin
read_state_reg <= read_state_next;
read_id_reg <= read_id_next;
read_addr_reg <= read_addr_next;
read_count_reg <= read_count_next;
read_size_reg <= read_size_next;
read_burst_reg <= read_burst_next;
s_axi_arready_reg <= s_axi_arready_next;
s_axi_rid_reg <= s_axi_rid_next;
s_axi_rlast_reg <= s_axi_rlast_next;
s_axi_rvalid_reg <= s_axi_rvalid_next;
if (mem_rd_en) begin
case({read_addr_valid, 3'b0})
MSIP_ADDR: begin
s_axi_rdata_reg <= csr_msip;
end
MTIMECMP_ADDR: begin
s_axi_rdata_reg <= csr_mtimecmp;
end
MTIME_ADDR: begin
s_axi_rdata_reg <= csr_mtime;
end
endcase
end
end
end
assign s_axi_ruser = 'b0;
assign s_axi_buser = 'b0;
endmodule
module ysyx_040991_axi_xbar #(
// Width of data bus in bits
parameter ysyx_040991_DATA_WIDTH = 64,
// Width of address bus in bits
parameter ADDR_WIDTH = 32,
// Width of wstrb (width of data bus in words)
parameter STRB_WIDTH = (ysyx_040991_DATA_WIDTH/8),
// Input ID field width (from AXI masters)
parameter S_ID_WIDTH = 4,
// Output ID field width (towards AXI slaves)
// Additional bits required for response routing
parameter M_ID_WIDTH = 4,
// Width of awuser signal
parameter AWUSER_WIDTH = 1,
// Width of wuser signal
parameter WUSER_WIDTH = 1,
// Width of buser signal
parameter BUSER_WIDTH = 1,
// Width of aruser signal
parameter ARUSER_WIDTH = 1,
// Width of ruser signal
parameter RUSER_WIDTH = 1
)(
input wire clk,
input wire rst,
/*
* AXI slave interface
*/
output wire [M_ID_WIDTH-1:0] io_master_awid,
output wire [ADDR_WIDTH-1:0] io_master_awaddr,
output wire [7:0] io_master_awlen,
output wire [2:0] io_master_awsize,
output wire [1:0] io_master_awburst,
output wire io_master_awlock,
output wire [3:0] io_master_awcache,
output wire [2:0] io_master_awprot,
output wire [3:0] io_master_awqos,
output wire [3:0] io_master_awregion,
output wire [AWUSER_WIDTH-1:0] io_master_awuser,
output wire io_master_awvalid,
input wire io_master_awready,
output wire [ysyx_040991_DATA_WIDTH-1:0] io_master_wdata,
output wire [STRB_WIDTH-1:0] io_master_wstrb,
output wire io_master_wlast,
output wire [WUSER_WIDTH-1:0] io_master_wuser,
output wire io_master_wvalid,
input wire io_master_wready,
input wire [M_ID_WIDTH-1:0] io_master_bid,
input wire [1:0] io_master_bresp,
input wire [BUSER_WIDTH-1:0] io_master_buser,
input wire io_master_bvalid,
output wire io_master_bready,
output wire [S_ID_WIDTH-1:0] io_master_arid,
output wire [ADDR_WIDTH-1:0] io_master_araddr,
output wire [7:0] io_master_arlen,
output wire [2:0] io_master_arsize,
output wire [1:0] io_master_arburst,
output wire io_master_arlock,
output wire [3:0] io_master_arcache,
output wire [2:0] io_master_arprot,
output wire [3:0] io_master_arqos,
output wire [3:0] io_master_arregion,
output wire [ARUSER_WIDTH-1:0] io_master_aruser,
output wire io_master_arvalid,
input wire io_master_arready,
input wire [S_ID_WIDTH-1:0] io_master_rid,
input wire [ysyx_040991_DATA_WIDTH-1:0] io_master_rdata,
input wire [1:0] io_master_rresp,
input wire io_master_rlast,
input wire [RUSER_WIDTH-1:0] io_master_ruser,
input wire io_master_rvalid,
output wire io_master_rready,
output wire [M_ID_WIDTH-1:0] clint_axi_awid,
output wire [ADDR_WIDTH-1:0] clint_axi_awaddr,
output wire [7:0] clint_axi_awlen,
output wire [2:0] clint_axi_awsize,
output wire [1:0] clint_axi_awburst,
output wire clint_axi_awlock,
output wire [3:0] clint_axi_awcache,
output wire [2:0] clint_axi_awprot,
output wire [3:0] clint_axi_awqos,
output wire [3:0] clint_axi_awregion,
output wire [AWUSER_WIDTH-1:0] clint_axi_awuser,
output wire clint_axi_awvalid,
input wire clint_axi_awready,
output wire [ysyx_040991_DATA_WIDTH-1:0] clint_axi_wdata,
output wire [STRB_WIDTH-1:0] clint_axi_wstrb,
output wire clint_axi_wlast,
output wire [WUSER_WIDTH-1:0] clint_axi_wuser,
output wire clint_axi_wvalid,
input wire clint_axi_wready,
input wire [M_ID_WIDTH-1:0] clint_axi_bid,
input wire [1:0] clint_axi_bresp,
input wire [BUSER_WIDTH-1:0] clint_axi_buser,
input wire clint_axi_bvalid,
output wire clint_axi_bready,
output wire [S_ID_WIDTH-1:0] clint_axi_arid,
output wire [ADDR_WIDTH-1:0] clint_axi_araddr,
output wire [7:0] clint_axi_arlen,
output wire [2:0] clint_axi_arsize,
output wire [1:0] clint_axi_arburst,
output wire clint_axi_arlock,
output wire [3:0] clint_axi_arcache,
output wire [2:0] clint_axi_arprot,
output wire [3:0] clint_axi_arqos,
output wire [3:0] clint_axi_arregion,
output wire [ARUSER_WIDTH-1:0] clint_axi_aruser,
output wire clint_axi_arvalid,
input wire clint_axi_arready,
input wire [S_ID_WIDTH-1:0] clint_axi_rid,
input wire [ysyx_040991_DATA_WIDTH-1:0] clint_axi_rdata,
input wire [1:0] clint_axi_rresp,
input wire clint_axi_rlast,
input wire [RUSER_WIDTH-1:0] clint_axi_ruser,
input wire clint_axi_rvalid,
output wire clint_axi_rready,
/*
* AXI master interface
*/
input wire [M_ID_WIDTH-1:0] m00_axi_awid,
input wire [ADDR_WIDTH-1:0] m00_axi_awaddr,
input wire [7:0] m00_axi_awlen,
input wire [2:0] m00_axi_awsize,
input wire [1:0] m00_axi_awburst,
input wire m00_axi_awlock,
input wire [3:0] m00_axi_awcache,
input wire [2:0] m00_axi_awprot,
input wire [3:0] m00_axi_awqos,
input wire [3:0] m00_axi_awregion,
input wire [AWUSER_WIDTH-1:0] m00_axi_awuser,
input wire m00_axi_awvalid,
output wire m00_axi_awready,
input wire [ysyx_040991_DATA_WIDTH-1:0] m00_axi_wdata,
input wire [STRB_WIDTH-1:0] m00_axi_wstrb,
input wire m00_axi_wlast,
input wire [WUSER_WIDTH-1:0] m00_axi_wuser,
input wire m00_axi_wvalid,
output wire m00_axi_wready,
output wire [M_ID_WIDTH-1:0] m00_axi_bid,
output wire [1:0] m00_axi_bresp,
output wire [BUSER_WIDTH-1:0] m00_axi_buser,
output wire m00_axi_bvalid,
input wire m00_axi_bready,
input wire [M_ID_WIDTH-1:0] m00_axi_arid,
input wire [ADDR_WIDTH-1:0] m00_axi_araddr,
input wire [7:0] m00_axi_arlen,
input wire [2:0] m00_axi_arsize,
input wire [1:0] m00_axi_arburst,
input wire m00_axi_arlock,
input wire [3:0] m00_axi_arcache,
input wire [2:0] m00_axi_arprot,
input wire [3:0] m00_axi_arqos,
input wire [3:0] m00_axi_arregion,
input wire [ARUSER_WIDTH-1:0] m00_axi_aruser,
input wire m00_axi_arvalid,
output wire m00_axi_arready,
output wire [M_ID_WIDTH-1:0] m00_axi_rid,
output wire [ysyx_040991_DATA_WIDTH-1:0] m00_axi_rdata,
output wire [1:0] m00_axi_rresp,
output wire m00_axi_rlast,
output wire [RUSER_WIDTH-1:0] m00_axi_ruser,
output wire m00_axi_rvalid,
input wire m00_axi_rready
);
wire mem_wen;
wire mmio_wen;
wire clint_wen;
assign mem_wen = (m00_axi_awaddr & 32'hf000_0000) == 32'h8000_0000;
assign mmio_wen = (m00_axi_awaddr & 32'hff00_0000) == 32'h3000_0000 || (m00_axi_awaddr & 32'hff00_0000) == 32'h1000_0000;
assign clint_wen = (m00_axi_awaddr & 32'hff00_0000) == 32'h0200_0000;
reg [2:0] write_channel;
localparam IDLE_WRITE = 3'b000;
localparam MEM_WRITE = 3'b001;
localparam CLINT_WRITE = 3'b100;
always @(posedge clk) begin
if (rst) begin
write_channel <= 3'b0;
end
else if (m00_axi_awvalid) begin
if (mem_wen || mmio_wen) begin
write_channel <= MEM_WRITE;
end
else if (clint_wen) begin
write_channel <= CLINT_WRITE;
end
else begin
write_channel <= IDLE_WRITE;
end
end
else if (m00_axi_bvalid) begin
write_channel <= IDLE_WRITE;
end
end
// aw
assign io_master_awid = (mem_wen || mmio_wen) ? m00_axi_awid : 'b0;
assign io_master_awaddr = (mem_wen || mmio_wen) ? m00_axi_awaddr : 'b0;
assign io_master_awlen = (mem_wen || mmio_wen) ? m00_axi_awlen : 'b0;
assign io_master_awsize = (mem_wen || mmio_wen) ? m00_axi_awsize : 'b0;
assign io_master_awburst = (mem_wen || mmio_wen) ? m00_axi_awburst : 'b0;
assign io_master_awlock = (mem_wen || mmio_wen) ? m00_axi_awlock : 'b0;
assign io_master_awcache = (mem_wen || mmio_wen) ? m00_axi_awcache : 'b0;
assign io_master_awprot = (mem_wen || mmio_wen) ? m00_axi_awprot : 'b0;
assign io_master_awqos = (mem_wen || mmio_wen) ? m00_axi_awqos : 'b0;
assign io_master_awregion = (mem_wen || mmio_wen) ? m00_axi_awregion : 'b0;
assign io_master_awuser = (mem_wen || mmio_wen) ? m00_axi_awuser : 'b0;
assign io_master_awvalid = (mem_wen || mmio_wen) ? m00_axi_awvalid : 'b0;
assign clint_axi_awid = clint_wen ? m00_axi_awid : 'b0;
assign clint_axi_awaddr = clint_wen ? m00_axi_awaddr : 'b0;
assign clint_axi_awlen = clint_wen ? m00_axi_awlen : 'b0;
assign clint_axi_awsize = clint_wen ? m00_axi_awsize : 'b0;
assign clint_axi_awburst = clint_wen ? m00_axi_awburst : 'b0;
assign clint_axi_awlock = clint_wen ? m00_axi_awlock : 'b0;
assign clint_axi_awcache = clint_wen ? m00_axi_awcache : 'b0;
assign clint_axi_awprot = clint_wen ? m00_axi_awprot : 'b0;
assign clint_axi_awqos = clint_wen ? m00_axi_awqos : 'b0;
assign clint_axi_awregion = clint_wen ? m00_axi_awregion : 'b0;
assign clint_axi_awuser = clint_wen ? m00_axi_awuser : 'b0;
assign clint_axi_awvalid = clint_wen ? m00_axi_awvalid : 'b0;
assign m00_axi_awready = (mem_wen || mmio_wen) ? io_master_awready : clint_wen ? clint_axi_awready : 'b0;
assign io_master_wstrb = (write_channel == MEM_WRITE) ? m00_axi_wstrb : 'b0;
assign io_master_wlast = (write_channel == MEM_WRITE) ? m00_axi_wlast : 'b0;
assign io_master_wuser = (write_channel == MEM_WRITE) ? m00_axi_wuser : 'b0;
assign io_master_wvalid = (write_channel == MEM_WRITE) ? m00_axi_wvalid : 'b0;
assign io_master_wdata = (write_channel == MEM_WRITE) ? m00_axi_wdata : 'b0;
assign clint_axi_wstrb = (write_channel == CLINT_WRITE) ? m00_axi_wstrb : 'b0;
assign clint_axi_wlast = (write_channel == CLINT_WRITE) ? m00_axi_wlast : 'b0;
assign clint_axi_wuser = (write_channel == CLINT_WRITE) ? m00_axi_wuser : 'b0;
assign clint_axi_wvalid = (write_channel == CLINT_WRITE) ? m00_axi_wvalid : 'b0;
assign clint_axi_wdata = (write_channel == CLINT_WRITE) ? m00_axi_wdata : 'b0;
assign m00_axi_wready = (write_channel == MEM_WRITE) ? io_master_wready : (write_channel == CLINT_WRITE) ? clint_axi_wready : 'b0;
assign m00_axi_bid = (write_channel == MEM_WRITE) ? io_master_bid : (write_channel == CLINT_WRITE) ? clint_axi_bid : 'b0;
assign m00_axi_bresp = (write_channel == MEM_WRITE) ? io_master_bresp : (write_channel == CLINT_WRITE) ? clint_axi_bresp : 'b0;
assign m00_axi_buser = (write_channel == MEM_WRITE) ? io_master_buser : (write_channel == CLINT_WRITE) ? clint_axi_buser : 'b0;
assign m00_axi_bvalid = (write_channel == MEM_WRITE) ? io_master_bvalid : (write_channel == CLINT_WRITE) ? clint_axi_bvalid : 'b0;
assign io_master_bready = (write_channel == MEM_WRITE) ? m00_axi_bready : 'b0;
assign clint_axi_bready = (write_channel == CLINT_WRITE) ? m00_axi_bready : 'b0;
wire mem_aren;
wire mmio_aren;
wire clint_aren;
assign mem_aren = (m00_axi_araddr & 32'hf000_0000) == 32'h8000_0000;
assign mmio_aren = (m00_axi_araddr & 32'hf000_0000) == 32'h3000_0000 || (m00_axi_araddr & 32'hf000_0000) == 32'h1000_0000;
assign clint_aren = (m00_axi_araddr & 32'hff00_0000) == 32'h0200_0000;
reg [2:0] read_channel;
localparam IDLE_READ = 3'b000;
localparam MEM_READ = 3'b001;
localparam CLINT_READ = 3'b100;
wire mem_rcomplete;
wire clint_rcomplete;
assign mem_rcomplete = io_master_rlast && io_master_rvalid && io_master_rready;
assign clint_rcomplete = clint_axi_rlast && clint_axi_rvalid && clint_axi_rready;
always @(posedge clk) begin
if (rst) begin
read_channel <= 3'b0;
end
else if (m00_axi_arvalid) begin
if (mem_aren || mmio_aren) begin
read_channel <= MEM_READ;
end
else if (clint_aren) begin
read_channel <= CLINT_READ;
end
end
else if (mem_rcomplete || clint_rcomplete) begin
read_channel <= IDLE_READ;
end
end
assign io_master_arid = (mem_aren || mmio_aren) ? {3'b001, m00_axi_arid[0]} : 'b0;
assign io_master_araddr = (mem_aren || mmio_aren) ? m00_axi_araddr : 'b0;
assign io_master_arlen = (mem_aren || mmio_aren) ? m00_axi_arlen : 'b0;
assign io_master_arsize = (mem_aren || mmio_aren) ? m00_axi_arsize : 'b0;
assign io_master_arburst = (mem_aren || mmio_aren) ? m00_axi_arburst : 'b0;
assign io_master_arlock = (mem_aren || mmio_aren) ? m00_axi_arlock : 'b0;
assign io_master_arcache = (mem_aren || mmio_aren) ? m00_axi_arcache : 'b0;
assign io_master_arprot = (mem_aren || mmio_aren) ? m00_axi_arprot : 'b0;
assign io_master_arqos = (mem_aren || mmio_aren) ? m00_axi_arqos : 'b0;
assign io_master_arregion = (mem_aren || mmio_aren) ? m00_axi_arregion : 'b0;
assign io_master_aruser = (mem_aren || mmio_aren) ? m00_axi_aruser : 'b0;
assign io_master_arvalid = (mem_aren || mmio_aren) ? m00_axi_arvalid : 'b0;
assign clint_axi_arid = clint_aren ? {3'b100, m00_axi_arid[0]} : 'b0;
assign clint_axi_araddr = clint_aren ? m00_axi_araddr : 'b0;
assign clint_axi_arlen = clint_aren ? m00_axi_arlen : 'b0;
assign clint_axi_arsize = clint_aren ? m00_axi_arsize : 'b0;
assign clint_axi_arburst = clint_aren ? m00_axi_arburst : 'b0;
assign clint_axi_arlock = clint_aren ? m00_axi_arlock : 'b0;
assign clint_axi_arcache = clint_aren ? m00_axi_arcache : 'b0;
assign clint_axi_arprot = clint_aren ? m00_axi_arprot : 'b0;
assign clint_axi_arqos = clint_aren ? m00_axi_arqos : 'b0;
assign clint_axi_arregion = clint_aren ? m00_axi_arregion : 'b0;
assign clint_axi_aruser = clint_aren ? m00_axi_aruser : 'b0;
assign clint_axi_arvalid = clint_aren ? m00_axi_arvalid : 'b0;
assign m00_axi_arready = (mem_aren || mmio_aren) ? io_master_arready : clint_aren ? clint_axi_arready : 'b0;
assign m00_axi_rid = (read_channel == MEM_READ) ? {3'b000, io_master_rid[0]} : (read_channel == CLINT_READ) ? {3'b000, clint_axi_rid[0]} : 'b0;
assign m00_axi_rdata = (read_channel == MEM_READ) ? io_master_rdata : (read_channel == CLINT_READ) ? clint_axi_rdata : 'b0;
assign m00_axi_rresp = (read_channel == MEM_READ) ? io_master_rresp : (read_channel == CLINT_READ) ? clint_axi_rresp : 'b0;
assign m00_axi_rlast = (read_channel == MEM_READ) ? io_master_rlast : (read_channel == CLINT_READ) ? clint_axi_rlast : 'b0;
assign m00_axi_ruser = (read_channel == MEM_READ) ? io_master_ruser : (read_channel == CLINT_READ) ? clint_axi_ruser : 'b0;
assign m00_axi_rvalid = (read_channel == MEM_READ) ? io_master_rvalid : (read_channel == CLINT_READ) ? clint_axi_rvalid : 'b0;
assign io_master_rready = (read_channel == MEM_READ) ? m00_axi_rready : 'b0;
assign clint_axi_rready = (read_channel == CLINT_READ) ? m00_axi_rready : 'b0;
endmodule
module ysyx_040991_BranchCondGen #(
parameter ysyx_040991_DATA_WIDTH = 64
)(
input [ysyx_040991_DATA_WIDTH-1:0] reg1,
input [ysyx_040991_DATA_WIDTH-1:0] reg2,
output br_eq,
output br_lt,
output br_ltu
);
assign br_eq = reg1 == reg2 ? 1 : 0;
assign br_lt = $signed(reg1) < $signed (reg2) ? 1 : 0;
assign br_ltu = reg1 < reg2 ? 1 : 0;
endmodule
module ysyx_040991_cache_core (
input clk,
input rst,
// ports from cpu core
input valid,
input uncache, // io read or write
input op, // 1: write, 0: read
input [`ysyx_040991_CACHE_INDEX_WD-1:0] index,
input [`ysyx_040991_CACHE_TAG_WD-1:0] tag, // ppn
input [`ysyx_040991_CACHE_OFFSET_WD-1:0] offset,
// input [3:0] size, // 4'b1000: 8bit; 4'b0100: 16bit; 4'b0010: 32bit; 4'b0001: 64bit
input [7:0] wstrb,
input [63:0] wdata,
output reg addr_ok,
output reg data_ok,
output reg [63:0] rdata,
// to axi4 converter module
// read request
output rd_req,
output reg [3:0] rd_type, // 4'b1000: 8bit; 4'b0100: 16bit; 4'b0010: 32bit; 4'b0001: 64bit; 4'b0000: cache line(256bit)
output reg [31:0] rd_addr, // init burst address
input rd_rdy,
// return data
input ret_valid,
input ret_last,
input [63:0] ret_data,
// write request
output reg wr_req,
output reg [3:0] wr_type, // 4'b1000: 8bit; 4'b0100: 16bit; 4'b0010: 32bit; 4'b0001: 64bit; 4'b0000: cache line(256bit)
output reg [31:0] wr_addr, // init burst address
output reg [7:0] wr_wstrb, // only valid when wr_type is 4'b0000 & 4'b0001 & 4'b0010 & 4'b0100
output reg [255:0] wr_data,
input wr_rdy,
// sync
output reg icache_sync_wready,
input [`ysyx_040991_CACHE_INDEX_WD-1 : 0] icache_sync_waddr,
input [`ysyx_040991_CACHE_SYNC_BUS_WD-1 : 0] icache_sync_wbus,
input icache_sync_wvalid,
output reg dcache_sync_rready,
input dcache_sync_rvalid,
input [`ysyx_040991_CACHE_INDEX_WD-1 : 0] dcache_sync_raddr,
output [`ysyx_040991_CACHE_SYNC_BUS_WD-1 : 0] dcache_sync_rbus,
// data_bank0 of ram0
input [128 -1:0] ram0_bank0_Q,
output ram0_bank0_CEN,
output ram0_bank0_WEN,
output [128 -1:0] ram0_bank0_BWEN,
output [6 -1:0] ram0_bank0_A,
output [128 -1:0] ram0_bank0_D,
// data_bank1 of ram0
input [128 -1:0] ram0_bank1_Q,
output ram0_bank1_CEN,
output ram0_bank1_WEN,
output [128 -1:0] ram0_bank1_BWEN,
output [6 -1:0] ram0_bank1_A,
output [128 -1:0] ram0_bank1_D,
// data_bank0 of ram1
input [128 -1:0] ram1_bank0_Q,
output ram1_bank0_CEN,
output ram1_bank0_WEN,
output [128 -1:0] ram1_bank0_BWEN,
output [6 -1:0] ram1_bank0_A,
output [128 -1:0] ram1_bank0_D,
// data_bank1 of ram1
input [128 -1:0] ram1_bank1_Q,
output ram1_bank1_CEN,
output ram1_bank1_WEN,
output [128 -1:0] ram1_bank1_BWEN,
output [6 -1:0] ram1_bank1_A,
output [128 -1:0] ram1_bank1_D
);
// cache configuration parameters
localparam AXI_BURST_LEN = 3;
// main state machine control
localparam STATE_IDLE = 7'b0000001;
localparam STATE_LOOKUP = 7'b0000010;
localparam STATE_MISS = 7'b0000100;
localparam STATE_REPLACE = 7'b0001000;
localparam STATE_REFILL = 7'b0010000;
localparam STATE_SYNC_RD = 7'b0100000;
localparam STATE_SYNC_WR = 7'b1000000;
reg [6:0] curr_state;
reg [6:0] next_state;
localparam WB_STATE_IDLE = 1'b0;
localparam WB_STATE_WRITE = 1'b1;
reg wb_curr_state;
reg wb_next_state;
always @(posedge clk) begin
if (rst) begin
curr_state <= STATE_IDLE;
end
else begin
curr_state <= next_state;
end
end
// rams
// tagv ram
wire way0_tagv_wen, way1_tagv_wen;
wire way0_tagv_cen, way1_tagv_cen;
wire [`ysyx_040991_CACHE_TAG_WD:0] way0_tagv_din, way1_tagv_din, tagv_din;
wire [`ysyx_040991_CACHE_INDEX_WD-1:0] tagv_addr;
wire way0_v_dout, way1_v_dout;
wire [`ysyx_040991_CACHE_TAG_WD-1:0] way0_tag_dout, way1_tag_dout;
ysyx_040991_tag_v_ram u_tag_v_ram0(
.clk (clk ),
.rst (rst ),
.cen (way0_tagv_cen ),
.addr (tagv_addr ),
.din (way0_tagv_din ),
.wen (way0_tagv_wen ),
.dout ({way0_tag_dout, way0_v_dout} )
);
ysyx_040991_tag_v_ram u_tag_v_ram1(
.clk (clk ),
.rst (rst ),
.cen (way1_tagv_cen ),
.addr (tagv_addr ),
.din (way1_tagv_din ),
.wen (way1_tagv_wen ),
.dout ({way1_tag_dout, way1_v_dout} )
);
// dirty bit ram
wire way0_d_cen, way1_d_cen;
wire way0_d_wen, way1_d_wen;
wire way0_d_din, way1_d_din, d_din;
wire [`ysyx_040991_CACHE_INDEX_WD-1:0] d_addr;
wire way0_d_dout, way1_d_dout;
ysyx_040991_cache_d_ram u_cache_d_ram0(
.clk (clk ),
.rst (rst ),
.cen (way0_d_cen ),
.addr (d_addr ),
.din (way0_d_din ),
.wen (way0_d_wen ),
.dout (way0_d_dout )
);
ysyx_040991_cache_d_ram u_cache_d_ram1(
.clk (clk ),
.rst (rst ),
.cen (way1_d_cen ),
.addr (d_addr ),
.din (way1_d_din ),
.wen (way1_d_wen ),
.dout (way1_d_dout )
);
// data ram
wire way0_data_cen, way1_data_cen;
wire way0_data_wen, way1_data_wen;
wire [`ysyx_040991_CACHE_INDEX_WD-1:0] data_raddr;
wire [`ysyx_040991_CACHE_INDEX_WD-1:0] data_waddr;
wire [`ysyx_040991_CACHE_LINE_WD-1:0] way0_data_din, way1_data_din, data_din;
wire [1:0] data_rbank;
wire [3:0] data_wbank;
wire [7:0] data_wstrb;
wire [`ysyx_040991_CACHE_LINE_WD-1:0] way0_data_dout, way1_data_dout;
ysyx_040991_cache_data_ram u_cache_data_ram0(
.cen (way0_data_cen ),
.raddr (data_raddr ),
.waddr (data_waddr ),
.din (way0_data_din ),
.wen (way0_data_wen ),
.rbank (data_rbank ),
.wbank (data_wbank ),
.wmask (data_wstrb ),
.dout (way0_data_dout ),
.bank0_Q (ram0_bank0_Q ),
.bank0_CEN (ram0_bank0_CEN ),
.bank0_WEN (ram0_bank0_WEN ),
.bank0_BWEN (ram0_bank0_BWEN ),
.bank0_A (ram0_bank0_A ),
.bank0_D (ram0_bank0_D ),
.bank1_Q (ram0_bank1_Q ),
.bank1_CEN (ram0_bank1_CEN ),
.bank1_WEN (ram0_bank1_WEN ),
.bank1_BWEN (ram0_bank1_BWEN ),
.bank1_A (ram0_bank1_A ),
.bank1_D (ram0_bank1_D )
);
ysyx_040991_cache_data_ram u_cache_data_ram1(
.cen (way1_data_cen ),
.raddr (data_raddr ),
.waddr (data_waddr ),
.din (way1_data_din ),
.wen (way1_data_wen ),
.rbank (data_rbank ),
.wbank (data_wbank ),
.wmask (data_wstrb ),
.dout (way1_data_dout ),
.bank0_Q (ram1_bank0_Q ),
.bank0_CEN (ram1_bank0_CEN ),
.bank0_WEN (ram1_bank0_WEN ),
.bank0_BWEN (ram1_bank0_BWEN ),
.bank0_A (ram1_bank0_A ),
.bank0_D (ram1_bank0_D ),
.bank1_Q (ram1_bank1_Q ),
.bank1_CEN (ram1_bank1_CEN ),
.bank1_WEN (ram1_bank1_WEN ),
.bank1_BWEN (ram1_bank1_BWEN ),
.bank1_A (ram1_bank1_A ),
.bank1_D (ram1_bank1_D )
);
// data path
// request buffer
reg op_r ;
reg [`ysyx_040991_CACHE_INDEX_WD -1:0] index_r ;
reg [`ysyx_040991_CACHE_TAG_WD -1:0] tag_r ;
reg [`ysyx_040991_CACHE_OFFSET_WD -1:0] offset_r;
reg [7:0] wstrb_r ;
reg [63:0] wdata_r ;
reg uncache_r;
wire rb_en; // request buffer change
always @(posedge clk) begin
if (rst) begin
op_r <= 'b0;
index_r <= 'b0;
tag_r <= 'b0;
offset_r <= 'b0;
wstrb_r <= 'b0;
wdata_r <= 'b0;
uncache_r <= 'b0;
end
else if (rb_en) begin
op_r <= op;
index_r <= index;
tag_r <= tag;
offset_r <= offset;
wstrb_r <= wstrb;
wdata_r <= wdata;
uncache_r <= uncache;
end
else begin
op_r <= op_r;
index_r <= index_r;
tag_r <= tag_r;
offset_r <= offset_r;
wstrb_r <= wstrb_r;
wdata_r <= wdata_r;
uncache_r <= uncache_r;
end
end
// tag compare
wire way0_hit, way1_hit;
wire cache_hit;
assign way0_hit = way0_v_dout && (way0_tag_dout == tag_r);
assign way1_hit = way1_v_dout && (way1_tag_dout == tag_r);
assign cache_hit = way0_hit || way1_hit;
// data select
wire [63:0] way0_load_data, way1_load_data;
wire [63:0] load_res;
assign way0_load_data = way0_data_dout[offset_r[4:3]*64 +: 64]; // offset from physical address
assign way1_load_data = way1_data_dout[offset_r[4:3]*64 +: 64];
assign load_res = ({64{way0_hit}} & way0_load_data)
| ({64{way1_hit}} & way1_load_data);
wire [`ysyx_040991_CACHE_LINE_WD-1:0] replace_data;
wire replace_way;
// control signals
wire hit_write;
assign hit_write = (curr_state == STATE_LOOKUP) && (op_r == `ysyx_040991_CACHE_OP_WRITE) && cache_hit;
// hit write hazard
reg hazard_case0;
wire hazard_case1;
wire is_dirty;
// LRU record
reg way0_age;
reg way1_age;
always @(posedge clk) begin
if (rst) begin
way0_age <= 1'b1;
way1_age <= 1'b0;
end
else if (way0_hit) begin
way0_age <= 1'b1;
way1_age <= 1'b0;
end
else if (way1_hit) begin
way0_age <= 1'b0;
way1_age <= 1'b1;
end
end
assign replace_way = ((way0_age == 1'b0) & 1'b0)
| ((way1_age == 1'b0) & 1'b1);
// miss buffer
reg mb_replace_way;
reg [1:0] mb_rbeat_cnt;
always @(posedge clk) begin
if (rst) begin
mb_replace_way <= 1'b0;
end
else if (curr_state == STATE_MISS && next_state == STATE_REPLACE) begin
mb_replace_way <= replace_way;
end
else begin
mb_replace_way <= mb_replace_way;
end
end
wire rnext;
assign rnext = ret_valid;
always @(posedge clk) begin
if (rst || (curr_state == STATE_REPLACE && next_state == STATE_REFILL)) begin
mb_rbeat_cnt <= 2'b0;
end
else if (rnext && (mb_rbeat_cnt != AXI_BURST_LEN)) begin
mb_rbeat_cnt <= mb_rbeat_cnt + 1'b1;
end
else begin
mb_rbeat_cnt <= mb_rbeat_cnt;
end
end
// write buffer
reg wb_valid;
reg wb_way_id;
reg [1:0] wb_bank_id;
reg [`ysyx_040991_CACHE_INDEX_WD-1:0] wb_index;
reg [7:0] wb_bank_wstrb;
reg [63:0] wb_wdata;
always @(posedge clk) begin
if (rst) begin
wb_valid <= 1'b0;
wb_way_id <= 1'b0;
wb_bank_id <= 2'b0;
wb_index <= {`ysyx_040991_CACHE_INDEX_WD{1'b0}};
wb_bank_wstrb <= 8'b0;
wb_wdata <= 64'b0;
end
else if (hit_write) begin
wb_valid <= 1'b1;
wb_way_id <= (way0_hit & 1'b0) | (way1_hit & 1'b1);
wb_bank_id <= offset_r[4:3];
wb_index <= index_r;
wb_bank_wstrb <= wstrb_r;
wb_wdata <= wdata_r;
end
else begin
wb_valid <= 1'b0;
wb_way_id <= 1'b0;
wb_bank_id <= 2'b0;
wb_index <= {`ysyx_040991_CACHE_INDEX_WD{1'b0}};
wb_bank_wstrb <= 8'b0;
wb_wdata <= 64'b0;
end
end
// control path
// write buffer state machine
always @(posedge clk) begin
if (rst) begin
wb_curr_state <= WB_STATE_IDLE;
end
else begin
wb_curr_state <= wb_next_state;
end
end
always @(*) begin
case (wb_curr_state)
WB_STATE_IDLE: begin
if (hit_write) begin
wb_next_state = WB_STATE_WRITE;
end
else begin
wb_next_state = WB_STATE_IDLE;
end
end
WB_STATE_WRITE: begin
if (hit_write && wb_valid) begin
wb_next_state = WB_STATE_WRITE;
end
else if (!hit_write && wb_valid) begin
wb_next_state = WB_STATE_IDLE;
end
else begin
wb_next_state = WB_STATE_WRITE;
end
end
default: begin
wb_next_state = WB_STATE_IDLE;
end
endcase
end
always @(*) begin
case (curr_state)
STATE_IDLE: begin
if (dcache_sync_rvalid) begin
next_state = STATE_SYNC_RD;
end
else if (icache_sync_wvalid) begin
next_state = STATE_SYNC_WR;
end
else if(valid) begin
next_state = STATE_LOOKUP;
end
else if (!valid) begin
next_state = STATE_IDLE;
end
else begin
next_state = STATE_IDLE;
end
end
STATE_LOOKUP: begin
if (!cache_hit || uncache_r) begin
next_state = STATE_MISS;
end
else if ((!valid && cache_hit) || hazard_case1) begin
next_state = STATE_IDLE;
end
else if (valid && cache_hit) begin
next_state = STATE_LOOKUP;
end
else begin
next_state = STATE_IDLE;
end
end
STATE_MISS: begin
if (!wr_rdy) begin
next_state = STATE_MISS;
end
else begin
next_state = STATE_REPLACE;
end
end
STATE_REPLACE: begin
if ((uncache_r && op_r == `ysyx_040991_CACHE_OP_WRITE) || rd_rdy)begin
next_state = STATE_REFILL;
end
else if (!rd_rdy) begin
next_state = STATE_REPLACE;
end
else begin
next_state = STATE_IDLE;
end
end
STATE_REFILL: begin
if((ret_valid && ret_last) || (uncache_r && op_r == `ysyx_040991_CACHE_OP_WRITE)) begin
next_state = STATE_IDLE;
end
else begin
next_state = STATE_REFILL;
end
end
STATE_SYNC_RD: begin
if (!dcache_sync_rvalid) begin
next_state = STATE_IDLE;
end
else begin
next_state = STATE_SYNC_RD;
end
end
STATE_SYNC_WR: begin
if (!icache_sync_wvalid) begin
next_state = STATE_IDLE;
end
else begin
next_state = STATE_SYNC_WR;
end
end
default: begin
next_state = STATE_IDLE;
end
endcase
end
// case 0
// bypass rdata
always @(posedge clk) begin
if (rst) begin
hazard_case0 <= 1'b0;
end
else begin
hazard_case0 <= hit_write && valid && (op == `ysyx_040991_CACHE_OP_READ) && ({tag, index, offset} == {tag_r, index_r, offset_r});
end
end
// case 1
// stall main state machine idle
assign hazard_case1 = (wb_curr_state == WB_STATE_WRITE) && valid && (offset[4] == wb_bank_id[1]);
assign rb_en = next_state == STATE_LOOKUP;
assign is_dirty = (!mb_replace_way & (way0_d_dout && way0_v_dout)) | (mb_replace_way & (way1_d_dout && way1_v_dout));
// sync data to be written
wire [`ysyx_040991_CACHE_TAG_WD:0] way0_sync_tagv;
wire [`ysyx_040991_CACHE_TAG_WD:0] way1_sync_tagv;
wire way0_sync_d;
wire way1_sync_d;
wire [`ysyx_040991_CACHE_LINE_WD-1:0] way0_sync_data;
wire [`ysyx_040991_CACHE_LINE_WD-1:0] way1_sync_data;
assign way0_sync_tagv = icache_sync_wbus[257+:22];
assign way1_sync_tagv = icache_sync_wbus[536+:22];
assign way0_sync_d = icache_sync_wbus[256+:1];
assign way1_sync_d = icache_sync_wbus[535+:1];
assign way0_sync_data = icache_sync_wbus[0+:256];
assign way1_sync_data = icache_sync_wbus[279+:256];
// ram control
// tagv ram
assign way0_tagv_cen = (dcache_sync_rvalid || icache_sync_wvalid)
| (valid && next_state == STATE_LOOKUP) // look up
| ((curr_state == STATE_MISS && next_state == STATE_REPLACE) & !replace_way) // replace
| (ret_valid && !mb_replace_way); // refill
assign way1_tagv_cen = (dcache_sync_rvalid || icache_sync_wvalid)
| (valid && next_state == STATE_LOOKUP) // look up
| ((curr_state == STATE_MISS && next_state == STATE_REPLACE) & replace_way) // replace
| (ret_valid && mb_replace_way); // refill
assign way0_tagv_wen = icache_sync_wvalid
| (!uncache_r && (ret_valid && !mb_replace_way)); // refill
assign way1_tagv_wen = icache_sync_wvalid
| (!uncache_r && (ret_valid && mb_replace_way)); // refill
assign tagv_din = {(`ysyx_040991_CACHE_TAG_WD+1){ret_valid}} & {tag_r, 1'b1}; // refill
assign way0_tagv_din = icache_sync_wvalid ? way0_sync_tagv : tagv_din;
assign way1_tagv_din = icache_sync_wvalid ? way1_sync_tagv : tagv_din;
assign tagv_addr = ({`ysyx_040991_CACHE_INDEX_WD{dcache_sync_rvalid}} & dcache_sync_raddr)
| ({`ysyx_040991_CACHE_INDEX_WD{icache_sync_wvalid}} & icache_sync_waddr)
| ({`ysyx_040991_CACHE_INDEX_WD{valid && next_state == STATE_LOOKUP}} & index) // look up
| ({`ysyx_040991_CACHE_INDEX_WD{curr_state == STATE_MISS && next_state == STATE_REPLACE}} & index_r) // replace; read the way to be updated
| ({`ysyx_040991_CACHE_INDEX_WD{ret_valid}} & index_r); // refill; update the way required update
// d ram
assign way0_d_cen = (dcache_sync_rvalid || icache_sync_wvalid)
| (wb_valid && wb_way_id == 1'b0) // hit write
| ((curr_state == STATE_MISS && next_state == STATE_REPLACE) & !replace_way) // replace
| (ret_valid && !mb_replace_way); // replace way
assign way1_d_cen = (dcache_sync_rvalid || icache_sync_wvalid)
| (wb_valid && wb_way_id == 1'b1) // hit write
| ((curr_state == STATE_MISS && next_state == STATE_REPLACE) & replace_way) // replace
| (ret_valid && mb_replace_way); // replace way
assign way0_d_wen = icache_sync_wvalid
| (!uncache_r && ((wb_valid && wb_way_id == 1'b0) // hit write
| ((curr_state == STATE_MISS && next_state == STATE_REPLACE) & !replace_way) // replace
| (ret_valid && !mb_replace_way)));
assign way1_d_wen = icache_sync_wvalid
| (!uncache_r && ((wb_valid && wb_way_id == 1'b1) // hit write
| ((curr_state == STATE_MISS && next_state == STATE_REPLACE) & replace_way) // replace
| (ret_valid && mb_replace_way)));
assign d_din = (wb_valid & 1'b1) // hit write
| ((ret_valid && op_r==`ysyx_040991_CACHE_OP_WRITE) & 1'b1) // refill; store: dirty
| ((ret_valid && op_r==`ysyx_040991_CACHE_OP_READ) & 1'b0); // refill; load: not dirty
assign way0_d_din = icache_sync_wvalid ? way0_sync_d : d_din;
assign way1_d_din = icache_sync_wvalid ? way1_sync_d : d_din;
assign d_addr = ({`ysyx_040991_CACHE_INDEX_WD{dcache_sync_rvalid}} & dcache_sync_raddr)
| ({`ysyx_040991_CACHE_INDEX_WD{icache_sync_wvalid}} & icache_sync_waddr)
| ({`ysyx_040991_CACHE_INDEX_WD{wb_valid}} & wb_index) //
| ({`ysyx_040991_CACHE_INDEX_WD{curr_state == STATE_MISS && next_state == STATE_REPLACE}} & index_r) // read the way to be updated
| ({`ysyx_040991_CACHE_INDEX_WD{ret_valid}} & index_r); // refill: update the way required
// data ram
assign way0_data_cen = (dcache_sync_rvalid || icache_sync_wvalid)
| (valid && next_state == STATE_LOOKUP) // lookup
| (wb_valid && wb_way_id == 1'b0) // hit write
| ((curr_state == STATE_MISS && next_state == STATE_REPLACE) & !replace_way) // replace
| (ret_valid && !mb_replace_way); // refill
assign way1_data_cen = (dcache_sync_rvalid || icache_sync_wvalid)
| (valid && next_state == STATE_LOOKUP) // lookup
| (wb_valid && wb_way_id == 1'b1) // hit write
| ((curr_state == STATE_MISS && next_state == STATE_REPLACE) & replace_way) // replace
| (ret_valid && mb_replace_way); // refill
assign way0_data_wen = icache_sync_wvalid
| (!uncache_r && ((wb_valid && wb_way_id == 1'b0) // hit write
| (ret_valid && !mb_replace_way))); // refill
assign way1_data_wen = icache_sync_wvalid
| (!uncache_r && ((wb_valid && wb_way_id == 1'b1) // hit write
| (ret_valid && mb_replace_way))); // refill
wire [63:0] refill_datamask;
assign refill_datamask = {{8{wstrb_r[7]}}, {8{wstrb_r[6]}}, {8{wstrb_r[5]}}, {8{wstrb_r[4]}}, {8{wstrb_r[3]}}, {8{wstrb_r[2]}}, {8{wstrb_r[1]}}, {8{wstrb_r[0]}}};
assign data_din = ({256{wb_valid}} & {4{wb_wdata}}) // hit write
| ({256{ret_valid && op_r == `ysyx_040991_CACHE_OP_READ}} & {4{ret_data}}) // refill: always refill ret data for load operations
| ({256{ret_valid && op_r == `ysyx_040991_CACHE_OP_WRITE && mb_rbeat_cnt == offset_r[4:3]}} & {4{(ret_data & ~refill_datamask) | (wdata_r & refill_datamask)}}) // refill: store wdata_r in wbank
| ({256{ret_valid && op_r == `ysyx_040991_CACHE_OP_WRITE && mb_rbeat_cnt != offset_r[4:3]}} & {4{ret_data}}); // refill: store ret data for the rest banks
assign way0_data_din = icache_sync_wvalid ? way0_sync_data : data_din;
assign way1_data_din = icache_sync_wvalid ? way1_sync_data : data_din;
assign data_raddr = ({`ysyx_040991_CACHE_INDEX_WD{dcache_sync_rvalid}} & dcache_sync_raddr)
| ({`ysyx_040991_CACHE_INDEX_WD{valid && next_state == STATE_LOOKUP && !hazard_case0}} & index) // lookup
| ({`ysyx_040991_CACHE_INDEX_WD{curr_state == STATE_MISS && next_state == STATE_REPLACE}} & index_r); // replace: read the way to be updated
assign data_waddr = ({`ysyx_040991_CACHE_INDEX_WD{icache_sync_wvalid}} & icache_sync_waddr)
| ({`ysyx_040991_CACHE_INDEX_WD{wb_valid}} & wb_index) // hit write: update the way that hit write
| ({`ysyx_040991_CACHE_INDEX_WD{ret_valid}} & index_r); // refill: update the way required update
assign data_wstrb = ({8{icache_sync_wvalid}} & 8'hff)
| ({8{wb_valid}} & wb_bank_wstrb)
| ({8{ret_valid}} & 8'hff); // refill: always refill ret data for load operations
assign data_rbank = ({2{dcache_sync_rvalid}} & 2'b11)
| ({2{valid && next_state == STATE_LOOKUP && !hazard_case1}} & (({2{offset[4] == 'b0}} & 2'b01)
|({2{offset[4] == 'b1}} & 2'b10))) // lookup
| ({2{curr_state == STATE_MISS && next_state == STATE_REPLACE}} & 2'b11); // replace
assign data_wbank = ({4{icache_sync_wvalid}} & 4'b1111)
| ({4{wb_valid}} & (({4{wb_bank_id == 2'b00}} & 4'b0001)
|({4{wb_bank_id == 2'b01}} & 4'b0010)
|({4{wb_bank_id == 2'b10}} & 4'b0100)
|({4{wb_bank_id == 2'b11}} & 4'b1000))) // hit write
| ({4{ret_valid}} & (({4{mb_rbeat_cnt == 2'b00}} & 4'b0001)
|({4{mb_rbeat_cnt == 2'b01}} & 4'b0010)
|({4{mb_rbeat_cnt == 2'b10}} & 4'b0100)
|({4{mb_rbeat_cnt == 2'b11}} & 4'b1000))); // refill
// outputs
reg [6:0] curr_state_d;
always @(posedge clk) begin
if (rst) begin
curr_state_d <= STATE_IDLE;
end
else begin
curr_state_d <= curr_state;
end
end
// to cpu core
always @(*) begin
if (curr_state == STATE_IDLE && !hazard_case1) begin
addr_ok = 1'b1;
end
else if (curr_state == STATE_LOOKUP && next_state == STATE_LOOKUP && cache_hit && valid) begin
addr_ok = 1'b1;
end
else begin
addr_ok = 1'b0;
end
end
always @(*) begin
if (curr_state == STATE_LOOKUP && cache_hit) begin
data_ok = 1'b1;
end
else if (curr_state == STATE_LOOKUP && wb_curr_state == WB_STATE_WRITE && cache_hit) begin
data_ok = 1'b1;
end
else if (uncache_r && (op_r == `ysyx_040991_CACHE_OP_WRITE) && (curr_state_d == STATE_MISS) && (curr_state == STATE_REPLACE)) begin
data_ok = 1'b1;
end
else if (curr_state == STATE_REFILL && ret_valid && (mb_rbeat_cnt == offset_r[4:3] || (uncache_r && op_r == `ysyx_040991_CACHE_OP_READ))) begin
data_ok = 1'b1;
end
else begin
data_ok = 1'b0;
end
end
wire [63:0] wb_datamask;
assign wb_datamask = {{8{wb_bank_wstrb[7]}}, {8{wb_bank_wstrb[6]}}, {8{wb_bank_wstrb[5]}}, {8{wb_bank_wstrb[4]}}, {8{wb_bank_wstrb[3]}}, {8{wb_bank_wstrb[2]}}, {8{wb_bank_wstrb[1]}}, {8{wb_bank_wstrb[0]}}};
always @(*) begin
if (curr_state == STATE_LOOKUP && cache_hit && op_r == `ysyx_040991_CACHE_OP_READ && !hazard_case0) begin
rdata = load_res;
end
else if (curr_state == STATE_LOOKUP && hazard_case0) begin // bypass data for hazard case 0
rdata = (load_res & ~wb_datamask) | (wb_wdata & wb_datamask);
end
else if (curr_state == STATE_REFILL && ret_valid && (mb_rbeat_cnt == offset_r[4:3])) begin
rdata = ret_data;
end
else if (curr_state == STATE_REFILL && ret_valid && (uncache_r && op_r == `ysyx_040991_CACHE_OP_READ)) begin
if (tag_r[20 : 1] == 20'h1000_0) begin // uart
rdata = {8{ret_data[7:0]}};
end
else if (tag_r[20 : 5] == 16'h0200) begin // clint
rdata = ret_data;
end
else begin
rdata = {2{ret_data[31:0]}};
end
end
else begin
rdata = 64'b0;
end
end
// to axi4 module
// rd signals
assign rd_req = (curr_state == STATE_REPLACE) && (uncache_r ? op_r == `ysyx_040991_CACHE_OP_READ : 1'b1); // arvalid
always @(posedge clk) begin
if (rst) begin
rd_type <= 4'b0;
end
else if (next_state == STATE_REPLACE) begin
if (uncache_r) begin
if (tag_r[20 : 1] == 20'h1000_0) begin // uart
rd_type <= 4'b1000;
end
else if (tag_r[20 : 5] == 16'h0200) begin // clint
rd_type <= 4'b0001;
end
else begin
rd_type <= 4'b0010; // read 32 bit mmio
end
end
else begin
rd_type <= 4'b0000; // read cache line
end
end
else begin
rd_type <= 4'b0;
end
end
always @(posedge clk) begin
if (rst) begin
rd_addr <= 32'b0;
end
else if (next_state == STATE_REPLACE) begin
if (uncache_r) begin
if (tag_r[20 : 1] == 20'h1000_0) begin
rd_addr <= {tag_r, index_r, offset_r};
end
else if (tag_r[20 : 5] == 16'h0200) begin
rd_addr <= {tag_r, index_r, offset_r[4:3], 3'b0};
end
else begin
rd_addr <= {tag_r, index_r, offset_r[4:2], 2'b0}; // masked addr for 64bit
end
end
else begin
rd_addr <= {tag_r, index_r, 5'b0};
end
end
else begin
rd_addr <= 32'b0;
end
end
// wr signals
wire wr_flag;
assign wr_flag = (curr_state_d == STATE_MISS) && (curr_state == STATE_REPLACE);
always @(posedge clk) begin
if (rst) begin
wr_req <= 1'b0;
end
else if (wr_flag) begin // only valid for one cycle
if (uncache_r) begin
wr_req <= op_r == `ysyx_040991_CACHE_OP_WRITE;
end
else begin
wr_req <= is_dirty;
end
end
else begin
wr_req <= 1'b0;
end
end
assign replace_data = mb_replace_way ? way1_data_dout : way0_data_dout;
wire [`ysyx_040991_CACHE_TAG_WD-1:0] replace_tag;
assign replace_tag = mb_replace_way ? way1_tag_dout: way0_tag_dout;
always @(posedge clk) begin
if (rst) begin
wr_data <= 256'b0;
end
else if (wr_flag) begin
if (uncache_r) begin
wr_data <= {192'b0, wdata_r};
end
else begin
wr_data <= replace_data;
end
end
else begin
wr_data <= 256'b0;
end
end
always @(posedge clk) begin
if (rst) begin
wr_addr <= 32'b0;
end
else if (wr_flag) begin
if (uncache_r) begin
if (tag_r[20 : 1] == 20'h1000_0) begin // uart mmio
wr_addr <= {tag_r, index_r, offset_r}; // full addr
end
else if (tag_r[20 : 5] == 16'h0200) begin
wr_addr <= {tag_r, index_r, offset_r[4:3], 3'b0};
end
else begin
wr_addr <= {tag_r, index_r, offset_r[4:2], 2'b0};
end
end
else begin
wr_addr <= {replace_tag, index_r, 5'b0};
end
end
else begin
wr_addr <= 32'b0;
end
end
always @(posedge clk) begin
if (rst) begin
wr_type <= 4'b0;
end
else if (wr_flag) begin
if (uncache_r) begin
if (tag_r[20 : 1] == 20'h1000_0) begin // uart mmio
wr_type <= 4'b1000; // uart 8bit
end
else if (tag_r[20 : 5] == 16'h0200) begin
wr_type <= 4'b0001;
end
else begin
wr_type <= 4'b0010; // write 32bit data
end
end
else begin
wr_type <= 4'b0000; // write the entire cache line
end
end
else begin
wr_type <= 4'b0;
end
end
always @(posedge clk) begin
if (rst) begin
wr_wstrb <= 8'b0;
end
else if (wr_flag) begin
if (uncache_r) begin
if (tag_r[20 : 1] == 20'h1000_0) begin // uart mmio
wr_wstrb <= 8'b01; // uart 8bit
end
else if (tag_r[20 : 5] == 16'h0200) begin
wr_wstrb <= 8'hff;
end
else begin
if (offset_r[2] == 1'b0) begin
wr_wstrb <= 8'h0f;
end
else begin
wr_wstrb <= 8'hf0;
end
end
end
else begin
wr_wstrb <= 8'hff;
end
end
else begin
wr_wstrb <= 8'b0;
end
end
// sync signals
assign icache_sync_wready = curr_state == STATE_IDLE && next_state == STATE_IDLE;
assign dcache_sync_rready = curr_state == STATE_IDLE && next_state == STATE_IDLE;
assign dcache_sync_rbus = { way1_tag_dout, way1_v_dout, way1_d_dout, way1_data_dout,
way0_tag_dout, way0_v_dout, way0_d_dout, way0_data_dout};
endmodule
module ysyx_040991_cache_data_ram (
input cen,
input [`ysyx_040991_CACHE_INDEX_WD-1:0] raddr,
input [`ysyx_040991_CACHE_INDEX_WD-1:0] waddr,
input [`ysyx_040991_CACHE_LINE_WD-1:0] din,
input wen,
input [1:0] rbank,
input [3:0] wbank,
input [7:0] wmask,
output [`ysyx_040991_CACHE_LINE_WD-1:0] dout,
// data_bank0 ram0
input [128 -1:0] bank0_Q,
output bank0_CEN,
output bank0_WEN,
output [128 -1:0] bank0_BWEN,
output [6 -1:0] bank0_A,
output [128 -1:0] bank0_D,
// data_bank1 ram1
input [128 -1:0] bank1_Q,
output bank1_CEN,
output bank1_WEN,
output [128 -1:0] bank1_BWEN,
output [6 -1:0] bank1_A,
output [128 -1:0] bank1_D
);
wire [63:0] unused [0:3];
wire [63:0] wdata_mask;
assign wdata_mask = {{8{wmask[7]}}, {8{wmask[6]}}, {8{wmask[5]}}, {8{wmask[4]}}, {8{wmask[3]}}, {8{wmask[2]}}, {8{wmask[1]}}, {8{wmask[0]}}};
assign bank0_CEN = ~(cen & (wbank[0] || wbank[1] || rbank[0]));
assign bank0_WEN = ~(wen & (wbank[0] || wbank[1]));
assign bank0_BWEN = ~{wbank[1] ? wdata_mask : 64'b0, wbank[0] ? wdata_mask : 64'b0};
assign bank0_A = (rbank[0]) ? raddr : (wbank[0] || wbank[1]) ? waddr : 6'b0;
assign bank0_D = din[127:0]; //{din[64 +: 64], din[0 +: 64]};
assign bank1_CEN = ~(cen & (wbank[2] || wbank[3] || rbank[1]));
assign bank1_WEN = ~(wen & (wbank[2] || wbank[3]));
assign bank1_BWEN = ~{wbank[3] ? wdata_mask : 64'b0, wbank[2] ? wdata_mask : 64'b0};
assign bank1_A = (rbank[1]) ? raddr : (wbank[2] || wbank[3]) ? waddr : 6'b0;
assign bank1_D = din[255:128]; //{din[192 +: 64], din[128 +: 64]};
assign dout = {bank1_Q, bank0_Q};
endmodule
module ysyx_040991_cache_d_ram (
input clk,
input rst,
input cen,
input [`ysyx_040991_CACHE_INDEX_WD-1:0] addr,
input din,
input wen,
output reg dout
);
integer i;
reg d_ram [0:`ysyx_040991_CACHE_RAM_DEPTH-1];
always @(posedge clk) begin
if (rst) begin
for (i = 0; i < 2**`ysyx_040991_CACHE_INDEX_WD; i=i+1) begin
d_ram[i] <= 'b0;
end
end
else if (wen && cen) begin
d_ram[addr] <= din;
end
end
always @(posedge clk) begin
if (rst) begin
dout <= 'b0;
end
else begin
dout <= cen ? d_ram[addr] : 'b0;
end
end
endmodule
module ysyx_040991_cache_sync (
input clk,
input rst,
input es_fence,
output reg es_fence_complete,
input icache_sync_wready,
output reg [`ysyx_040991_CACHE_INDEX_WD-1 : 0] icache_sync_waddr,
output reg [`ysyx_040991_CACHE_SYNC_BUS_WD-1 : 0] icache_sync_wbus,
output reg icache_sync_wvalid,
input dcache_sync_rready,
output reg dcache_sync_rvalid,
output reg [`ysyx_040991_CACHE_INDEX_WD-1 : 0] dcache_sync_raddr,
input [`ysyx_040991_CACHE_SYNC_BUS_WD-1 : 0] dcache_sync_rbus
);
reg [6:0] sync_counter;
reg [1:0] curr_state, next_state;
reg [`ysyx_040991_CACHE_SYNC_BUS_WD-1 : 0] sync_bus_buffer;
localparam [1:0] STATE_IDLE = 2'b01;
localparam [1:0] STATE_SYNC = 2'b10;
always @(posedge clk) begin
if (rst) begin
curr_state <= STATE_IDLE;
end
else begin
curr_state <= next_state;
end
end
always @(*) begin
case (curr_state)
STATE_IDLE: begin
if (es_fence && icache_sync_wready && dcache_sync_rready) begin
next_state = STATE_SYNC;
end
else begin
next_state = STATE_IDLE;
end
end
STATE_SYNC: begin
if (sync_counter == 7'd65) begin
next_state = STATE_IDLE;
end
else begin
next_state = STATE_SYNC;
end
end
default: begin
next_state = STATE_IDLE;
end
endcase
end
always @(posedge clk) begin
if (rst) begin
sync_counter <= 'b0;
end
else if (curr_state == STATE_SYNC && sync_counter != 7'd65) begin
sync_counter <= sync_counter + 'b1;
end
else if (sync_counter == 7'd65) begin
sync_counter <= 'b0;
end
end
always @(posedge clk) begin
if (rst) begin
sync_bus_buffer <= 'b0;
end
else if (sync_counter >= 'd1 && sync_counter <= 'd64) begin
sync_bus_buffer <= dcache_sync_rbus;
end
else begin
sync_bus_buffer <= 'b0;
end
end
always @(posedge clk) begin
if (rst) begin
dcache_sync_rvalid <= 'b0;
end
else if (next_state == STATE_SYNC && sync_counter < 'd63) begin
dcache_sync_rvalid <= 1'b1;
end
else if (sync_counter == 'd63 && dcache_sync_rvalid) begin
dcache_sync_rvalid <= 1'b0;
end
else begin
dcache_sync_rvalid <= 1'b0;
end
end
always @(posedge clk) begin
if (rst) begin
icache_sync_wvalid <= 'b0;
end
else if (curr_state == STATE_SYNC && sync_counter >= 'd1 && sync_counter <= 'd64) begin
icache_sync_wvalid <= 1'b1;
end
else if (sync_counter == 'd65 && icache_sync_wvalid) begin
icache_sync_wvalid <= 1'b0;
end
else begin
icache_sync_wvalid <= 1'b0;
end
end
assign es_fence_complete = (curr_state == STATE_SYNC) && (sync_counter == 7'd65);
assign icache_sync_wbus = sync_bus_buffer;
assign dcache_sync_raddr = {6{dcache_sync_rvalid}} & sync_counter[5:0];
assign icache_sync_waddr = {6{icache_sync_wvalid}} & (sync_counter[5:0] - 'd2);
endmodule
module ysyx_040991_cache_top #(
// Thread ID Width
parameter integer C_M_AXI_ID_WIDTH = 4,
// Width of Address Bus
parameter integer C_M_AXI_ADDR_WIDTH = 32,
// Width of Data Bus
parameter integer C_M_AXI_ysyx_040991_DATA_WIDTH = 64,
// Width of User Write Address Bus
parameter integer C_M_AXI_AWUSER_WIDTH = 1,
// Width of User Read Address Bus
parameter integer C_M_AXI_ARUSER_WIDTH = 1,
// Width of User Write Data Bus
parameter integer C_M_AXI_WUSER_WIDTH = 1,
// Width of User Read Data Bus
parameter integer C_M_AXI_RUSER_WIDTH = 1,
// Width of User Response Bus
parameter integer C_M_AXI_BUSER_WIDTH = 1
)(
input clk,
input rst,
// ports of icache
input icache_valid ,
input icache_uncache ,
input icache_op , // 0: read only
input [`ysyx_040991_CACHE_INDEX_WD -1:0] icache_index ,
input [`ysyx_040991_CACHE_TAG_WD -1:0] icache_tag ,
input [`ysyx_040991_CACHE_OFFSET_WD -1:0] icache_offset ,
output icache_addr_ok ,
output icache_data_ok ,
output [63:0] icache_rdata ,
// ports of dcache
input dcache_valid ,
input dcache_uncache ,
input dcache_op , // 0: read, 1: write
input [`ysyx_040991_CACHE_INDEX_WD -1:0] dcache_index ,
input [`ysyx_040991_CACHE_TAG_WD -1:0] dcache_tag ,
input [`ysyx_040991_CACHE_OFFSET_WD -1:0] dcache_offset ,
input [ 7:0] dcache_wstrb ,
input [63:0] dcache_wdata ,
output dcache_addr_ok ,
output dcache_data_ok ,
output [63:0] dcache_rdata ,
input es_fence,
output es_fence_complete,
// axi port
// input wire M_AXI_ACLK,
// input wire M_AXI_ARESETN,
output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_AWID,
output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_AWADDR,
output wire [7 : 0] M_AXI_AWLEN,
output wire [2 : 0] M_AXI_AWSIZE,
output wire [1 : 0] M_AXI_AWBURST,
output wire M_AXI_AWLOCK,
output wire [3 : 0] M_AXI_AWCACHE,
output wire [2 : 0] M_AXI_AWPROT,
output wire [3 : 0] M_AXI_AWQOS,
output wire [3 : 0] M_AXI_AWREGION,
output wire [C_M_AXI_AWUSER_WIDTH-1 : 0] M_AXI_AWUSER,
output wire M_AXI_AWVALID,
input wire M_AXI_AWREADY,
output wire [C_M_AXI_ysyx_040991_DATA_WIDTH-1 : 0] M_AXI_WDATA,
output wire [C_M_AXI_ysyx_040991_DATA_WIDTH/8-1 : 0] M_AXI_WSTRB,
output wire M_AXI_WLAST,
output wire [C_M_AXI_WUSER_WIDTH-1 : 0] M_AXI_WUSER,
output wire M_AXI_WVALID,
input wire M_AXI_WREADY,
input wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_BID,
input wire [1 : 0] M_AXI_BRESP,
input wire [C_M_AXI_BUSER_WIDTH-1 : 0] M_AXI_BUSER,
input wire M_AXI_BVALID,
output wire M_AXI_BREADY,
output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_ARID,
output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_ARADDR,
output wire [7 : 0] M_AXI_ARLEN,
output wire [2 : 0] M_AXI_ARSIZE,
output wire [1 : 0] M_AXI_ARBURST,
output wire M_AXI_ARLOCK,
output wire [3 : 0] M_AXI_ARCACHE,
output wire [2 : 0] M_AXI_ARPROT,
output wire [3 : 0] M_AXI_ARQOS,
output wire [3 : 0] M_AXI_ARREGION,
output wire [C_M_AXI_ARUSER_WIDTH-1 : 0] M_AXI_ARUSER,
output wire M_AXI_ARVALID,
input wire M_AXI_ARREADY,
input wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_RID,
input wire [C_M_AXI_ysyx_040991_DATA_WIDTH-1 : 0] M_AXI_RDATA,
input wire [1 : 0] M_AXI_RRESP,
input wire M_AXI_RLAST,
input wire [C_M_AXI_RUSER_WIDTH-1 : 0] M_AXI_RUSER,
input wire M_AXI_RVALID,
output wire M_AXI_RREADY,
// icache
// data_bank0 of ram0
input [128 -1:0] icache_ram0_bank0_Q,
output icache_ram0_bank0_CEN,
output icache_ram0_bank0_WEN,
output [128 -1:0] icache_ram0_bank0_BWEN,
output [6 -1:0] icache_ram0_bank0_A,
output [128 -1:0] icache_ram0_bank0_D,
// data_bank1 of ram0
input [128 -1:0] icache_ram0_bank1_Q,
output icache_ram0_bank1_CEN,
output icache_ram0_bank1_WEN,
output [128 -1:0] icache_ram0_bank1_BWEN,
output [6 -1:0] icache_ram0_bank1_A,
output [128 -1:0] icache_ram0_bank1_D,
// data_bank0 of ram1
input [128 -1:0] icache_ram1_bank0_Q,
output icache_ram1_bank0_CEN,
output icache_ram1_bank0_WEN,
output [128 -1:0] icache_ram1_bank0_BWEN,
output [6 -1:0] icache_ram1_bank0_A,
output [128 -1:0] icache_ram1_bank0_D,
// data_bank1 of ram1
input [128 -1:0] icache_ram1_bank1_Q,
output icache_ram1_bank1_CEN,
output icache_ram1_bank1_WEN,
output [128 -1:0] icache_ram1_bank1_BWEN,
output [6 -1:0] icache_ram1_bank1_A,
output [128 -1:0] icache_ram1_bank1_D,
// dcache
// data_bank0 of ram0
input [128 -1:0] dcache_ram0_bank0_Q,
output dcache_ram0_bank0_CEN,
output dcache_ram0_bank0_WEN,
output [128 -1:0] dcache_ram0_bank0_BWEN,
output [6 -1:0] dcache_ram0_bank0_A,
output [128 -1:0] dcache_ram0_bank0_D,
// data_bank1 of ram0
input [128 -1:0] dcache_ram0_bank1_Q,
output dcache_ram0_bank1_CEN,
output dcache_ram0_bank1_WEN,
output [128 -1:0] dcache_ram0_bank1_BWEN,
output [6 -1:0] dcache_ram0_bank1_A,
output [128 -1:0] dcache_ram0_bank1_D,
// data_bank0 of ram1
input [128 -1:0] dcache_ram1_bank0_Q,
output dcache_ram1_bank0_CEN,
output dcache_ram1_bank0_WEN,
output [128 -1:0] dcache_ram1_bank0_BWEN,
output [6 -1:0] dcache_ram1_bank0_A,
output [128 -1:0] dcache_ram1_bank0_D,
// data_bank1 of ram1
input [128 -1:0] dcache_ram1_bank1_Q,
output dcache_ram1_bank1_CEN,
output dcache_ram1_bank1_WEN,
output [128 -1:0] dcache_ram1_bank1_BWEN,
output [6 -1:0] dcache_ram1_bank1_A,
output [128 -1:0] dcache_ram1_bank1_D
);
wire icache_rd_req ;
wire [ 3:0] icache_rd_type ;
wire [ 31:0] icache_rd_addr ;
wire icache_rd_rdy ;
wire icache_ret_valid ;
wire icache_ret_last ;
wire [ 63:0] icache_ret_data ;
wire dcache_rd_req ;
wire [ 3:0] dcache_rd_type ;
wire [ 31:0] dcache_rd_addr ;
wire dcache_rd_rdy ;
wire dcache_ret_valid ;
wire dcache_ret_last ;
wire [ 63:0] dcache_ret_data ;
wire dcache_wr_req ;
wire [ 3:0] dcache_wr_type ;
wire [ 31:0] dcache_wr_addr ;
wire [ 7:0] dcache_wr_wstrb ;
wire [255:0] dcache_wr_data ;
wire dcache_wr_rdy ;
wire icache_sync_wready;
wire [`ysyx_040991_CACHE_INDEX_WD-1 : 0] icache_sync_waddr;
wire [`ysyx_040991_CACHE_SYNC_BUS_WD-1 : 0] icache_sync_wbus;
wire icache_sync_wvalid;
wire dcache_sync_rready;
wire dcache_sync_rvalid;
wire [`ysyx_040991_CACHE_INDEX_WD-1 : 0] dcache_sync_raddr;
wire [`ysyx_040991_CACHE_SYNC_BUS_WD-1 : 0] dcache_sync_rbus;
// unused wires
wire wr_req_unused ;
wire [3:0] wr_type_unused ;
wire [31:0] wr_addr_unused ;
wire [7:0] wr_wstrb_unused;
wire [255:0] wr_data_unused ;
wire dcache_sync_rready_unused;
wire dcache_sync_raddr_unused;
wire [`ysyx_040991_CACHE_SYNC_BUS_WD-1:0]dcache_sync_rbus_unused;
wire icache_sync_wready_unused;
ysyx_040991_cache_core icache_core(
.clk (clk ),
.rst (rst ),
.valid (icache_valid ),
.uncache (icache_uncache ),
.op (icache_op ),
.index (icache_index ),
.tag (icache_tag ),
.offset (icache_offset ),
.wstrb ('b0 ), // not required for icahce
.wdata ('b0 ), // not required for icahce
.addr_ok (icache_addr_ok ),
.data_ok (icache_data_ok ),
.rdata (icache_rdata ),
.rd_req (icache_rd_req ),
.rd_type (icache_rd_type ),
.rd_addr (icache_rd_addr ),
.rd_rdy (icache_rd_rdy ),
.ret_valid (icache_ret_valid ),
.ret_last (icache_ret_last ),
.ret_data (icache_ret_data ),
.wr_req (wr_req_unused ), // not required for icahce
.wr_type (wr_type_unused ), // not required for icahce
.wr_addr (wr_addr_unused ), // not required for icahce
.wr_wstrb (wr_wstrb_unused ), // not required for icahce
.wr_data (wr_data_unused ), // not required for icahce
.wr_rdy (1'b1 ),
.icache_sync_wready (icache_sync_wready ),
.icache_sync_waddr (icache_sync_waddr ),
.icache_sync_wbus (icache_sync_wbus ),
.icache_sync_wvalid (icache_sync_wvalid ),
.dcache_sync_rready (dcache_sync_rready_unused ), // not required for icahce
.dcache_sync_rvalid ('b0 ), // not required for icahce
.dcache_sync_raddr ('b0 ), // not required for icahce
.dcache_sync_rbus (dcache_sync_rbus_unused ), // not required for icahce
.ram0_bank0_Q (icache_ram0_bank0_Q ),
.ram0_bank0_CEN (icache_ram0_bank0_CEN ),
.ram0_bank0_WEN (icache_ram0_bank0_WEN ),
.ram0_bank0_BWEN (icache_ram0_bank0_BWEN ),
.ram0_bank0_A (icache_ram0_bank0_A ),
.ram0_bank0_D (icache_ram0_bank0_D ),
.ram0_bank1_Q (icache_ram0_bank1_Q ),
.ram0_bank1_CEN (icache_ram0_bank1_CEN ),
.ram0_bank1_WEN (icache_ram0_bank1_WEN ),
.ram0_bank1_BWEN (icache_ram0_bank1_BWEN ),
.ram0_bank1_A (icache_ram0_bank1_A ),
.ram0_bank1_D (icache_ram0_bank1_D ),
.ram1_bank0_Q (icache_ram1_bank0_Q ),
.ram1_bank0_CEN (icache_ram1_bank0_CEN ),
.ram1_bank0_WEN (icache_ram1_bank0_WEN ),
.ram1_bank0_BWEN (icache_ram1_bank0_BWEN ),
.ram1_bank0_A (icache_ram1_bank0_A ),
.ram1_bank0_D (icache_ram1_bank0_D ),
.ram1_bank1_Q (icache_ram1_bank1_Q ),
.ram1_bank1_CEN (icache_ram1_bank1_CEN ),
.ram1_bank1_WEN (icache_ram1_bank1_WEN ),
.ram1_bank1_BWEN (icache_ram1_bank1_BWEN ),
.ram1_bank1_A (icache_ram1_bank1_A ),
.ram1_bank1_D (icache_ram1_bank1_D )
);
ysyx_040991_cache_core dcache_core(
.clk (clk ),
.rst (rst ),
.valid (dcache_valid ),
.uncache (dcache_uncache ),
.op (dcache_op ),
.index (dcache_index ),
.tag (dcache_tag ),
.offset (dcache_offset ),
.wstrb (dcache_wstrb ),
.wdata (dcache_wdata ),
.addr_ok (dcache_addr_ok ),
.data_ok (dcache_data_ok ),
.rdata (dcache_rdata ),
.rd_req (dcache_rd_req ),
.rd_type (dcache_rd_type ),
.rd_addr (dcache_rd_addr ),
.rd_rdy (dcache_rd_rdy ),
.ret_valid (dcache_ret_valid ),
.ret_last (dcache_ret_last ),
.ret_data (dcache_ret_data ),
.wr_req (dcache_wr_req ),
.wr_type (dcache_wr_type ),
.wr_addr (dcache_wr_addr ),
.wr_wstrb (dcache_wr_wstrb ),
.wr_data (dcache_wr_data ),
.wr_rdy (dcache_wr_rdy ),
.icache_sync_wready (icache_sync_wready_unused ),
.icache_sync_waddr ('b0 ),
.icache_sync_wbus ('b0 ),
.icache_sync_wvalid ('b0 ),
.dcache_sync_rready (dcache_sync_rready ),
.dcache_sync_rvalid (dcache_sync_rvalid ),
.dcache_sync_raddr (dcache_sync_raddr ),
.dcache_sync_rbus (dcache_sync_rbus ),
.ram0_bank0_Q (dcache_ram0_bank0_Q ),
.ram0_bank0_CEN (dcache_ram0_bank0_CEN ),
.ram0_bank0_WEN (dcache_ram0_bank0_WEN ),
.ram0_bank0_BWEN (dcache_ram0_bank0_BWEN ),
.ram0_bank0_A (dcache_ram0_bank0_A ),
.ram0_bank0_D (dcache_ram0_bank0_D ),
.ram0_bank1_Q (dcache_ram0_bank1_Q ),
.ram0_bank1_CEN (dcache_ram0_bank1_CEN ),
.ram0_bank1_WEN (dcache_ram0_bank1_WEN ),
.ram0_bank1_BWEN (dcache_ram0_bank1_BWEN ),
.ram0_bank1_A (dcache_ram0_bank1_A ),
.ram0_bank1_D (dcache_ram0_bank1_D ),
.ram1_bank0_Q (dcache_ram1_bank0_Q ),
.ram1_bank0_CEN (dcache_ram1_bank0_CEN ),
.ram1_bank0_WEN (dcache_ram1_bank0_WEN ),
.ram1_bank0_BWEN (dcache_ram1_bank0_BWEN ),
.ram1_bank0_A (dcache_ram1_bank0_A ),
.ram1_bank0_D (dcache_ram1_bank0_D ),
.ram1_bank1_Q (dcache_ram1_bank1_Q ),
.ram1_bank1_CEN (dcache_ram1_bank1_CEN ),
.ram1_bank1_WEN (dcache_ram1_bank1_WEN ),
.ram1_bank1_BWEN (dcache_ram1_bank1_BWEN ),
.ram1_bank1_A (dcache_ram1_bank1_A ),
.ram1_bank1_D (dcache_ram1_bank1_D )
);
ysyx_040991_axi_bridge
#(
.C_M_AXI_ID_WIDTH (C_M_AXI_ID_WIDTH ),
.C_M_AXI_ADDR_WIDTH (C_M_AXI_ADDR_WIDTH ),
.C_M_AXI_ysyx_040991_DATA_WIDTH (C_M_AXI_ysyx_040991_DATA_WIDTH ),
.C_M_AXI_AWUSER_WIDTH (C_M_AXI_AWUSER_WIDTH ),
.C_M_AXI_ARUSER_WIDTH (C_M_AXI_ARUSER_WIDTH ),
.C_M_AXI_WUSER_WIDTH (C_M_AXI_WUSER_WIDTH ),
.C_M_AXI_RUSER_WIDTH (C_M_AXI_RUSER_WIDTH ),
.C_M_AXI_BUSER_WIDTH (C_M_AXI_BUSER_WIDTH )
)
u_axi_bridge(
.M_AXI_ACLK (clk ),
.M_AXI_ARESETN (!rst ),
.icache_rd_req (icache_rd_req ),
.icache_rd_type (icache_rd_type ),
.icache_rd_addr (icache_rd_addr ),
.icache_rd_rdy (icache_rd_rdy ),
.icache_ret_valid (icache_ret_valid ),
.icache_ret_last (icache_ret_last ),
.icache_ret_data (icache_ret_data ),
.dcache_rd_req (dcache_rd_req ),
.dcache_rd_type (dcache_rd_type ),
.dcache_rd_addr (dcache_rd_addr ),
.dcache_rd_rdy (dcache_rd_rdy ),
.dcache_ret_valid (dcache_ret_valid ),
.dcache_ret_last (dcache_ret_last ),
.dcache_ret_data (dcache_ret_data ),
.dcache_wr_req (dcache_wr_req ),
.dcache_wr_type (dcache_wr_type ),
.dcache_wr_addr (dcache_wr_addr ),
.dcache_wr_wstrb (dcache_wr_wstrb ),
.dcache_wr_data (dcache_wr_data ),
.dcache_wr_rdy (dcache_wr_rdy ),
.M_AXI_AWID (M_AXI_AWID ),
.M_AXI_AWADDR (M_AXI_AWADDR ),
.M_AXI_AWLEN (M_AXI_AWLEN ),
.M_AXI_AWSIZE (M_AXI_AWSIZE ),
.M_AXI_AWBURST (M_AXI_AWBURST ),
.M_AXI_AWLOCK (M_AXI_AWLOCK ),
.M_AXI_AWCACHE (M_AXI_AWCACHE ),
.M_AXI_AWPROT (M_AXI_AWPROT ),
.M_AXI_AWQOS (M_AXI_AWQOS ),
.M_AXI_AWREGION (M_AXI_AWREGION ),
.M_AXI_AWUSER (M_AXI_AWUSER ),
.M_AXI_AWVALID (M_AXI_AWVALID ),
.M_AXI_AWREADY (M_AXI_AWREADY ),
.M_AXI_WDATA (M_AXI_WDATA ),
.M_AXI_WSTRB (M_AXI_WSTRB ),
.M_AXI_WLAST (M_AXI_WLAST ),
.M_AXI_WUSER (M_AXI_WUSER ),
.M_AXI_WVALID (M_AXI_WVALID ),
.M_AXI_WREADY (M_AXI_WREADY ),
.M_AXI_BID (M_AXI_BID ),
.M_AXI_BRESP (M_AXI_BRESP ),
.M_AXI_BUSER (M_AXI_BUSER ),
.M_AXI_BVALID (M_AXI_BVALID ),
.M_AXI_BREADY (M_AXI_BREADY ),
.M_AXI_ARID (M_AXI_ARID ),
.M_AXI_ARADDR (M_AXI_ARADDR ),
.M_AXI_ARLEN (M_AXI_ARLEN ),
.M_AXI_ARSIZE (M_AXI_ARSIZE ),
.M_AXI_ARBURST (M_AXI_ARBURST ),
.M_AXI_ARLOCK (M_AXI_ARLOCK ),
.M_AXI_ARCACHE (M_AXI_ARCACHE ),
.M_AXI_ARPROT (M_AXI_ARPROT ),
.M_AXI_ARQOS (M_AXI_ARQOS ),
.M_AXI_ARREGION (M_AXI_ARREGION ),
.M_AXI_ARUSER (M_AXI_ARUSER ),
.M_AXI_ARVALID (M_AXI_ARVALID ),
.M_AXI_ARREADY (M_AXI_ARREADY ),
.M_AXI_RID (M_AXI_RID ),
.M_AXI_RDATA (M_AXI_RDATA ),
.M_AXI_RRESP (M_AXI_RRESP ),
.M_AXI_RLAST (M_AXI_RLAST ),
.M_AXI_RUSER (M_AXI_RUSER ),
.M_AXI_RVALID (M_AXI_RVALID ),
.M_AXI_RREADY (M_AXI_RREADY )
);
ysyx_040991_cache_sync u_cache_sync(
.clk (clk ),
.rst (rst ),
.es_fence (es_fence ),
.es_fence_complete (es_fence_complete ),
.icache_sync_wready (icache_sync_wready ),
.icache_sync_waddr (icache_sync_waddr ),
.icache_sync_wbus (icache_sync_wbus ),
.icache_sync_wvalid (icache_sync_wvalid ),
.dcache_sync_rready (dcache_sync_rready ),
.dcache_sync_rvalid (dcache_sync_rvalid ),
.dcache_sync_raddr (dcache_sync_raddr ),
.dcache_sync_rbus (dcache_sync_rbus )
);
endmodule
module ysyx_040991_csr_forwarding_unit(
// ms to es
input ms_csr_wen,
input [11:0] ms_csr_waddr,
// ws to es
input ws_csr_wen,
input [11:0] ws_csr_waddr,
// id signals
input [11:0] es_csr_raddr,
output [2:0] es_csr_rdata_sel
);
wire ms_csr_bypass;
wire ws_csr_bypass;
assign ms_csr_bypass = ms_csr_wen && (ms_csr_waddr == es_csr_raddr);
assign ws_csr_bypass = ws_csr_wen && (ws_csr_waddr == es_csr_raddr);
// [0] csr_rdata
assign es_csr_rdata_sel[0] = ~ms_csr_bypass && ~ws_csr_bypass;
// [1] ms result
assign es_csr_rdata_sel[1] = ms_csr_bypass;
// [2] ws result
assign es_csr_rdata_sel[2] = ~ms_csr_bypass && ws_csr_bypass;
endmodule
module ysyx_040991_csr(
input clk,
input rst,
// external interrupt
input timer_intr,
// from es
input [11:0] csr_raddr,
output [63:0] csr_rdata,
// from ws
input csr_wen,
input [11:0] csr_waddr,
input [63:0] csr_wdata,
input [ 5:0] ws_exception,
input ws_exception_valid,
input [63:0] ws_exception_pc,
output [63:0] csr_branch_pc,
// masked interrupt output
output timer_interrupt_en
);
// Machine Trap Setup
reg [63:0] csr_mstatus;
reg [63:0] csr_mie;
reg [63:0] csr_mtvec;
// Machine Trap Handling
reg [63:0] csr_mscratch;
reg [63:0] csr_mepc;
reg [63:0] csr_mcause;
reg [63:0] csr_mip;
wire ysyx_040991_MIP_MTIP;
reg [63:0] csr_mhartid;
// Machine Counter/Timers
reg [ 1:0] csr_mpriv;
reg [63:0] csr_mcycle;
wire [1:0] irq_priv;
assign timer_interrupt_en = csr_mie[`ysyx_040991_MIP_MTIP] && csr_mstatus[`ysyx_040991_MSTATUS_MIE] && ysyx_040991_MIP_MTIP;
assign irq_priv = `ysyx_040991_PRIV_MACHINE;
// end
// csr read port
assign csr_rdata = ({64{csr_raddr[11:0] == `ysyx_040991_CSR_MSTATUS_ADDR }} & csr_mstatus )
| ({64{csr_raddr[11:0] == `ysyx_040991_CSR_MTVEC_ADDR }} & csr_mtvec )
| ({64{csr_raddr[11:0] == `ysyx_040991_CSR_MSCRATCH_ADDR}} & csr_mscratch )
| ({64{csr_raddr[11:0] == `ysyx_040991_CSR_MIE_ADDR }} & csr_mie )
| ({64{csr_raddr[11:0] == `ysyx_040991_CSR_MIP_ADDR }} & csr_mip )
| ({64{csr_raddr[11:0] == `ysyx_040991_CSR_MEPC_ADDR }} & csr_mepc )
| ({64{csr_raddr[11:0] == `ysyx_040991_CSR_MCAUSE_ADDR }} & csr_mcause )
| ({64{csr_raddr[11:0] == `ysyx_040991_CSR_MCYCLE_ADDR }} & csr_mcycle )
| ({64{csr_raddr[11:0] == `ysyx_040991_CSR_MCYCLE_ADDR }} & csr_mhartid );
wire is_interrupt;
wire is_exception;
wire is_mret;
// exception[5:0] [5:4] exception, interrupt, ret [3:0] type
assign is_mret = (ws_exception[5:4] == `ysyx_040991_EXCEPTION_ERET) && ws_exception_valid;
assign is_interrupt = (ws_exception[5:4] == `ysyx_040991_EXCEPTION_INTERRUPT) && ws_exception_valid && timer_interrupt_en;
assign is_exception = (ws_exception[5:4] == `ysyx_040991_EXCEPTION_EXCEPTION) && ws_exception_valid;
wire [3:0] interrupt_type;
wire [3:0] exception_type;
assign interrupt_type = ws_exception[3:0];
assign exception_type = ws_exception[3:0];
// csr write port
always @(posedge clk) begin
if (rst) begin
csr_mpriv <= `ysyx_040991_PRIV_MACHINE;
end
else begin
csr_mpriv <= `ysyx_040991_PRIV_MACHINE;
end
end
always @(posedge clk) begin
if (rst) begin
csr_mepc <= 64'b0;
end
else if (is_interrupt && irq_priv == `ysyx_040991_PRIV_MACHINE) begin
csr_mepc <= ws_exception_pc;
end
else if (is_exception) begin
csr_mepc <= ws_exception_pc;
end
else if (csr_wen && csr_waddr == `ysyx_040991_CSR_MEPC_ADDR) begin
csr_mepc <= csr_wdata;
end
end
always @(posedge clk) begin
if (rst) begin
csr_mcause <= 64'b0;
end
else if (is_interrupt && irq_priv == `ysyx_040991_PRIV_MACHINE) begin
csr_mcause <= ({64{interrupt_type == `ysyx_040991_IRQ_M_SOFT }} & {1'b1, 59'b0, `ysyx_040991_IRQ_M_SOFT })
| ({64{interrupt_type == `ysyx_040991_IRQ_M_TIMER }} & {1'b1, 59'b0, `ysyx_040991_IRQ_M_TIMER})
| ({64{interrupt_type == `ysyx_040991_IRQ_M_EXT }} & {1'b1, 59'b0, `ysyx_040991_IRQ_M_EXT });
end
else if (is_exception) begin
csr_mcause <= {60'b0, exception_type};
end
else if (csr_wen && csr_waddr == `ysyx_040991_CSR_MCAUSE_ADDR) begin
csr_mcause <= {csr_wdata[63], 59'b0, csr_wdata[3:0]};
end
end
always @(posedge clk) begin
if (rst) begin
csr_mstatus <= 64'h1800;
end
else if (is_interrupt && irq_priv == `ysyx_040991_PRIV_MACHINE) begin
csr_mstatus[`ysyx_040991_MSTATUS_MIE] <= 1'b0;
csr_mstatus[`ysyx_040991_MSTATUS_MPIE] <= csr_mstatus[`ysyx_040991_MSTATUS_MIE];
csr_mstatus[`ysyx_040991_MSTATUS_MPP] <= irq_priv;
end
else if (is_mret) begin
csr_mstatus[`ysyx_040991_MSTATUS_MIE] <= csr_mstatus[`ysyx_040991_MSTATUS_MPIE];
csr_mstatus[`ysyx_040991_MSTATUS_MPIE] <= 1'b1;
csr_mstatus[`ysyx_040991_MSTATUS_MPP] <= irq_priv;
end
else if (is_exception) begin
csr_mstatus[`ysyx_040991_MSTATUS_MIE] <= 1'b0;
csr_mstatus[`ysyx_040991_MSTATUS_MPIE] <= csr_mstatus[`ysyx_040991_MSTATUS_MIE];
csr_mstatus[`ysyx_040991_MSTATUS_MPP] <= csr_mpriv;
end
else if (csr_wen && csr_waddr == `ysyx_040991_CSR_MSTATUS_ADDR) begin
csr_mstatus <= {(csr_wdata[14:13] == 2'b11) | (csr_wdata[16:15] == 2'b11), csr_wdata[62:0]};
end
end
always @(posedge clk) begin
if (rst) begin
csr_mtvec <= 64'b0;
end
else if(csr_waddr == `ysyx_040991_CSR_MTVEC_ADDR && csr_wen) begin
csr_mtvec <= csr_wdata;
end
end
always @(posedge clk) begin
if (rst) begin
csr_mie <= 64'b0;
end
else if(csr_waddr == `ysyx_040991_CSR_MIE_ADDR && csr_wen) begin
csr_mie <= csr_wdata;
end
end
always @(posedge clk) begin
if (rst) begin
csr_mscratch <= 64'b0;
end
else if(csr_waddr == `ysyx_040991_CSR_MSCRATCH_ADDR && csr_wen) begin
csr_mscratch <= csr_wdata;
end
end
always @(posedge clk) begin
if (rst) begin
csr_mhartid <= 64'b0;
end
else if(csr_waddr == `ysyx_040991_CSR_MHARTID_ADDR && csr_wen) begin
csr_mhartid <= csr_wdata;
end
end
assign ysyx_040991_MIP_MTIP = timer_intr;
assign csr_mip = {56'b0, ysyx_040991_MIP_MTIP, 7'b0};
always @(posedge clk) begin
if (rst) begin
csr_mcycle <= 64'b0;
end
else begin
csr_mcycle <= csr_mcycle + 1;
end
end
// csr branch
assign csr_branch_pc = ({64{is_interrupt && irq_priv == `ysyx_040991_PRIV_MACHINE}} & csr_mtvec)
| ({64{is_mret}} & csr_mepc)
| ({64{is_exception}} & csr_mtvec);
endmodule
module ysyx_040991_ctrl(
// input clk,
// input rst,
// branch and jal signals from id stage
input [`ysyx_040991_BR_BUS_WD :0] ds_branch_bus,
// jalr signals from exe stage
input [`ysyx_040991_BR_BUS_WD-1:0] es_branch_bus,
// to es stage
output ds_to_es_hold,
// to ms stage
// output es_to_ms_hold,
// to fs stage
output [`ysyx_040991_BR_BUS_WD:0] br_bus
);
// jalr > branch, jal
wire br_taken;
wire [`ysyx_040991_VADDR_WIDTH-1:0] br_target;
wire br_stall;
assign br_bus = {br_stall, br_taken, br_target};
wire br_j_en;
wire [`ysyx_040991_VADDR_WIDTH-1:0] br_j_pc;
assign {br_stall, br_j_en, br_j_pc} = ds_branch_bus;
wire jalr_en;
wire [`ysyx_040991_VADDR_WIDTH-1:0] jalr_pc;
assign {jalr_en, jalr_pc} = es_branch_bus;
assign br_target = jalr_en ? jalr_pc :
br_j_en ? br_j_pc :
64'b0 ;
assign br_taken = br_j_en || jalr_en;
assign ds_to_es_hold = jalr_en;
endmodule
module ysyx_040991_decoder_3_8(
input [2:0] in,
output [7:0] out
);
genvar i;
generate for (i=0; i < 8; i=i+1) begin: gen_for_dec_3_8
assign out[i] = (in == i);
end
endgenerate
endmodule
module ysyx_040991_decoder_7_128(
input [ 6:0] in,
output [127:0] out
);
genvar i;
generate for (i=0; i<128; i=i+1) begin : gen_for_dec_7_128
assign out[i] = (in == i);
end endgenerate
endmodule
module ysyx_040991_divider_cell(
input clk,
input rst,
input en,
input [64:0] A, // dividend
input [63:0] B, // divisor
input [63:0] S_ci, //
input [62:0] A_ci,
input [8:0] div_info_ci,
output reg [8:0] div_info_kp,
output reg [62:0] A_kp,
output reg [63:0] B_kp,
output reg rdy,
output reg [63:0] S,
output reg [63:0] R
);
reg tmp;
always @(posedge clk) begin
if (rst) begin
rdy <= 'b0;
S <= 'b0;
R <= 'b0;
B_kp <= 'b0;
A_kp <= 'b0;
div_info_kp <= 'b0;
end
else if (en) begin
rdy <= 1'b1;
B_kp <= B;
A_kp <= A_ci;
div_info_kp <= div_info_ci;
if (A >= {1'b0, B}) begin
S <= (S_ci<<1) + 1'b1;
{tmp, R} <= A - {1'b0, B};
end
else begin
S <= S_ci<<1;
{tmp, R} <= A;
end
end
else begin
rdy <= 'b0 ;
S <= 'b0 ;
R <= 'b0 ;
B_kp <= 'b0 ;
A_kp <= 'b0 ;
div_info_kp <= 'b0;
end
end
endmodule
module ysyx_040991_divider #(
parameter ysyx_040991_DATA_WIDTH = 64
)(
input clk,
input rst,
input [ysyx_040991_DATA_WIDTH-1:0] div_src1,
input [ysyx_040991_DATA_WIDTH-1:0] div_src2,
input [3:0] div_op,
input word_op, // word instructions
input div, // start div operation
// output reg complete, // after 66 iterations 0-65
output reg [ysyx_040991_DATA_WIDTH-1:0] div_wb_result
);
wire div_signed = div_op[3] | div_op[1]; // signed operands
// step1 fetch abs of dividend & divisor and signed info
wire A_sign, B_sign;
assign A_sign = div_src1[ysyx_040991_DATA_WIDTH-1];
assign B_sign = div_src2[ysyx_040991_DATA_WIDTH-1];
reg [63:0] A_init; // dividend init value
reg [63:0] B_init; // divisor init value
reg data_rdy;
reg [8:0] div_info;
wire [63:0] A_abs; // dividend abs
wire [63:0] B_abs; // divisor abs
wire [63:0] div_src1_word;
wire [63:0] div_src2_word;
assign div_src1_word = word_op ? {div_signed ? {32{div_src1[31]}} : 32'b0, div_src1[31:0]} : div_src1;
assign div_src2_word = word_op ? {div_signed ? {32{div_src2[31]}} : 32'b0, div_src2[31:0]} : div_src2;
assign A_abs = A_sign ? (~div_src1_word+1) : div_src1_word;
assign B_abs = B_sign ? (~div_src2_word+1) : div_src2_word;
wire B_zero;
assign B_zero = div_src2 == 'b0;
always @(posedge clk) begin
if (rst) begin
A_init <= 64'b0;
B_init <= 64'b0;
div_info <= 9'b0;
data_rdy <= 1'b0;
end
else if (div) begin
A_init <= div_signed ? (A_abs) : div_src1_word;
B_init <= div_signed ? (B_abs) : div_src2_word;
div_info <= {B_zero, A_sign, B_sign, div_signed, div_op, word_op};
data_rdy <= 1'b1;
end
else begin
A_init <= 64'b0;
B_init <= 64'b0;
div_info <= 9'b0;
data_rdy <= 1'b0;
end
end
// step2 64stage pipeline
wire [62:0] A_bus [0:63];
wire [63:0] B_bus [0:63];
wire [63:0] R_bus [0:63];
wire [63:0] rdy_bus;
wire [63:0] S_bus [0:63];
wire [8:0] div_info_bus [0:63];
// pipeline 0
ysyx_040991_divider_cell u_divider_step0 (
.clk (clk),
.rst (rst),
.en (data_rdy),
.A ({64'b0, A_init[63]}),
.B (B_init),
.S_ci (64'b0), // value of first S is 0
.A_ci (A_init[62:0]), // store A init value
.div_info_ci (div_info), // record div info
//output
.div_info_kp (div_info_bus[63]),
.A_kp (A_bus[63]), // pass value to next stage
.B_kp (B_bus[63]),
.rdy (rdy_bus[63]),
.S (S_bus[63]), // first s
.R (R_bus[63]) // risr
);
genvar i;
generate
for(i=1; i<=63; i=i+1) begin: sqrt_stepx
ysyx_040991_divider_cell u_divider_step (
.clk (clk),
.rst (rst),
.en (rdy_bus[63-i+1]),
.A ({R_bus[63-i+1], A_bus[63-i+1][63-i]}), // concact
.B (B_bus[63-i+1]),
.S_ci (S_bus[63-i+1]),
.A_ci (A_bus[63-i+1]),
.div_info_ci (div_info_bus[63-i+1]),
//output
.div_info_kp (div_info_bus[63-i]),
.B_kp (B_bus[63-i]),
.A_kp (A_bus[63-i]),
.rdy (rdy_bus[63-i]),
.S (S_bus[63-i]),
.R (R_bus[63-i])
);
end // block: sqrt_stepx
endgenerate
// step_3
wire [63:0] S_final_abs, S_final;
wire [63:0] R_final_abs, R_final;
assign S_final_abs = S_bus[0];
assign R_final_abs = R_bus[0];
// div info final
wire A_sign_final, B_sign_final, S_sign_final, R_sign_final;
wire [3:0] div_op_final;
wire word_op_final;
wire div_signed_final;
wire B_zero_final;
assign {
B_zero_final,
A_sign_final,
B_sign_final,
div_signed_final,
div_op_final,
word_op_final
} = div_info_bus[0];
assign S_sign_final = A_sign_final ^ B_sign_final;
assign R_sign_final = A_sign_final;
assign S_final = S_sign_final ? (~S_final_abs+1) : S_final_abs;
assign R_final = R_sign_final ? (~R_final_abs+1) : R_final_abs;
wire [63:0] div_result;
wire [63:0] rem_result;
wire [63:0] divw_result;
wire [63:0] remw_result;
assign div_result = {64{rdy_bus[0]}} & {B_zero_final ? S_final_abs : div_signed_final ? (S_final) : (S_final_abs)};
assign rem_result = {64{rdy_bus[0]}} & (div_signed_final ? (R_final) : (R_final_abs));
assign divw_result = {64{rdy_bus[0]}} & {B_zero_final ? {{32{S_final_abs[31]}}, S_final_abs[31:0]} : {{32{div_result[31]}}, div_result[31:0]}};
assign remw_result = {64{rdy_bus[0]}} & {{32{rem_result[31]}}, rem_result[31:0]};
wire op_div = div_op_final[ 3] & ~word_op_final;
wire op_divu = div_op_final[ 2] & ~word_op_final;
wire op_rem = div_op_final[ 1] & ~word_op_final;
wire op_remu = div_op_final[ 0] & ~word_op_final;
wire op_divw = div_op_final[ 3] & word_op_final;
wire op_divuw = div_op_final[ 2] & word_op_final;
wire op_remw = div_op_final[ 1] & word_op_final;
wire op_remuw = div_op_final[ 0] & word_op_final;
// reg rdy_d;
// always @(posedge clk) begin
// rdy_d <= rdy_bus[0];
// end
// divider result to mem stage directly
always @ (posedge clk) begin
// complete <= rdy_bus[0] & ~rdy_d; // complete signal only last one clock cycle
div_wb_result <= ({64{op_div |op_divu }} & div_result)
| ({64{op_divw |op_divuw }} & divw_result)
| ({64{op_rem |op_remu }} & rem_result)
| ({64{op_remw |op_remuw }} & remw_result);
end
endmodule
module ysyx_040991_exe_stage(
input clk ,
input rst ,
//allowin
input ms_allowin ,
output es_allowin ,
//from ds
input ds_to_es_valid,
input [`ysyx_040991_DS_TO_ES_BUS_WD -1:0] ds_to_es_bus ,
input [`ysyx_040991_EXCEPTION_WD-1:0] ds_to_es_exception,
//to ms
output es_to_ms_valid,
output [`ysyx_040991_ES_TO_MS_BUS_WD -1:0] es_to_ms_bus ,
output [`ysyx_040991_EXCEPTION_WD -1:0] es_to_ms_exception,
//to ctrl
input ds_to_es_hold,
output [`ysyx_040991_BR_BUS_WD -1:0] es_branch_bus,
input ws_flush,
input ms_is_exception,
// dcache ports
output dcache_valid ,
output dcache_uncache ,
output dcache_op , // 0: read, 1: write
output [`ysyx_040991_CACHE_INDEX_WD -1:0] dcache_index ,
output [`ysyx_040991_CACHE_TAG_WD -1:0] dcache_tag ,
output [`ysyx_040991_CACHE_OFFSET_WD -1:0] dcache_offset ,
output [ 7:0] dcache_wstrb ,
output [63:0] dcache_wdata ,
input dcache_addr_ok ,
output es_fence,
input es_fence_complete,
// forwarding bus
output [`ysyx_040991_ES_FORWARDING_BUS_WD -1:0] es_forwarding_bus,
// to multiplier divider
output [`ysyx_040991_DATA_WIDTH-1:0] es_alu_src1,
output [`ysyx_040991_DATA_WIDTH-1:0] es_alu_src2,
output [ 3:0] es_mul_op,
output [ 3:0] es_div_op,
output es_word_op,
output div,
// read csr file
output [11:0] es_csr_raddr,
input [63:0] es_csr_rdata,
// forwarding csr register
input [`ysyx_040991_CSR_FORWARDING_BUS_WD -1:0] ms_csr_forwarding_bus,
input [`ysyx_040991_CSR_FORWARDING_BUS_WD -1:0] ws_csr_forwarding_bus
);
reg es_valid ;
wire es_ready_go ;
reg [`ysyx_040991_DS_TO_ES_BUS_WD-1:0] ds_to_es_bus_r;
reg [`ysyx_040991_EXCEPTION_WD-1:0] ds_to_es_exception_r;
wire [10:0] es_alu_op ;
wire [ 4:0] es_src1_sel ;
wire [ 4:0] es_src2_sel ;
wire [ 6:0] es_load_op ;
wire [ 3:0] es_save_op ;
wire [ 5:0] es_wb_sel ;
wire es_rd_wen ;
wire es_data_ram_en ;
wire es_data_ram_wen ;
wire [ 4:0] es_rd_addr;
wire [`ysyx_040991_DATA_WIDTH-1:0] es_rs1_data ;
wire [`ysyx_040991_DATA_WIDTH-1:0] es_rs2_data ;
wire [`ysyx_040991_VADDR_WIDTH-1:0] es_pc ;
wire [31:0] es_inst;
wire es_csr_wen;
wire es_ds_stall;
wire es_jalr_en;
wire es_fence_i;
wire div_complete;
wire [63:0] es_csr_rdata_final;
assign {
es_fence_i ,
es_alu_op ,
es_src1_sel ,
es_src2_sel ,
es_load_op ,
es_save_op ,
es_mul_op ,
es_div_op ,
es_word_op ,
es_wb_sel ,
es_rd_wen ,
es_data_ram_en ,
es_data_ram_wen ,
es_rs1_data ,
es_rs2_data ,
es_rd_addr ,
es_jalr_en ,
es_csr_wen ,
es_ds_stall ,
es_pc ,
es_inst
} = ds_to_es_bus_r;
wire [`ysyx_040991_DATA_WIDTH-1:0] es_alu_result ;
assign es_to_ms_bus = {
// dcache_uncache ,
es_data_ram_en ,
es_wb_sel ,
es_load_op ,
es_rd_wen ,
es_rd_addr ,
es_alu_result ,
es_csr_rdata_final ,
es_csr_wen ,
es_pc ,
es_inst
};
wire [5:0] es_exception_curr;
assign es_exception_curr = ds_to_es_exception_r;
wire es_is_exception;
assign es_is_exception = |es_exception_curr[5:4];
assign es_forwarding_bus = {
es_ds_stall && es_valid ,
es_rd_wen && es_valid ,
es_rd_addr ,
es_alu_result
};
reg ws_flush_r;
always @(posedge clk) begin
if (rst) begin
ws_flush_r <= 1'b0;
end else if (ws_flush) begin
ws_flush_r <= 1'b1;
end else if (ds_to_es_valid && es_allowin) begin
ws_flush_r <= 1'b0;
end
end
assign es_ready_go = es_fence ? (es_fence_complete || es_is_exception || ms_is_exception || ws_flush || ws_flush_r) :
div ? (div_complete || es_is_exception || ms_is_exception || ws_flush || ws_flush_r) :
es_data_ram_en ? ((dcache_valid && dcache_addr_ok) || es_is_exception || ms_is_exception || ws_flush || ws_flush_r)
: 1'b1; // div div_complete signal generated from exe stage
assign es_allowin = !es_valid || es_ready_go && ms_allowin;
assign es_to_ms_valid = es_valid && es_ready_go && !(ws_flush || ws_flush_r);
always @(posedge clk) begin
if (rst) begin
es_valid <= 1'b0;
end
else if (es_allowin) begin
es_valid <= ds_to_es_valid && !ds_to_es_hold;
end
if (ds_to_es_valid && es_allowin) begin
ds_to_es_bus_r <= ds_to_es_bus;
ds_to_es_exception_r <= ds_to_es_exception;
end
end
// div signal generate
reg [7:0] div_cnt;
assign div = |es_div_op && es_valid || (div_cnt > 0);
assign div_complete = div_cnt == 8'd66;
always @(posedge clk) begin
if (rst) begin
div_cnt <= 8'b0;
end
else if (div_cnt == 8'd66) begin
div_cnt <= 8'b0;
end
else if (div) begin
div_cnt <= div_cnt + 1;
end
else begin
div_cnt <= 8'b0;
end
end
wire [`ysyx_040991_DATA_WIDTH-1:0] u_imm;
wire [`ysyx_040991_DATA_WIDTH-1:0] s_imm;
wire [`ysyx_040991_DATA_WIDTH-1:0] i_imm;
wire [`ysyx_040991_DATA_WIDTH-1:0] z_imm;
assign u_imm = {{32{es_inst[31]}}, es_inst[31:12], 12'b0};
assign s_imm = {{52{es_inst[31]}}, es_inst[31:25], es_inst[11:7]};
assign i_imm = {{52{es_inst[31]}}, es_inst[31:20]};
assign z_imm = {59'b0, es_inst[19:15]};
assign es_alu_src1 = ({`ysyx_040991_DATA_WIDTH{es_src1_sel[0]}} & es_rs1_data)
| ({`ysyx_040991_DATA_WIDTH{es_src1_sel[1]}} & u_imm )
| ({`ysyx_040991_DATA_WIDTH{es_src1_sel[2]}} & z_imm )
| ({`ysyx_040991_DATA_WIDTH{es_src1_sel[3]}} & ~es_rs1_data)
| ({`ysyx_040991_DATA_WIDTH{es_src1_sel[4]}} & ~z_imm );
assign es_alu_src2 = ({`ysyx_040991_DATA_WIDTH{es_src2_sel[0]}} & es_pc )
| ({`ysyx_040991_DATA_WIDTH{es_src2_sel[1]}} & i_imm )
| ({`ysyx_040991_DATA_WIDTH{es_src2_sel[2]}} & s_imm )
| ({`ysyx_040991_DATA_WIDTH{es_src2_sel[3]}} & es_rs2_data )
| ({`ysyx_040991_DATA_WIDTH{es_src2_sel[4]}} & es_csr_rdata_final );
assign es_csr_raddr = es_inst[31:20];
// csr bypassing logic
wire [2:0] es_csr_rdata_sel;
wire ms_csr_wen;
wire [11:0] ms_csr_waddr;
wire [63:0] ms_csr_wdata;
wire ws_csr_wen;
wire [11:0] ws_csr_waddr;
wire [63:0] ws_csr_wdata;
assign {ms_csr_wen, ms_csr_waddr, ms_csr_wdata} = ms_csr_forwarding_bus;
assign {ws_csr_wen, ws_csr_waddr, ws_csr_wdata} = ws_csr_forwarding_bus;
ysyx_040991_csr_forwarding_unit u_csr_forwarding_unit(
.ms_csr_wen (ms_csr_wen ),
.ms_csr_waddr (ms_csr_waddr ),
.ws_csr_wen (ws_csr_wen ),
.ws_csr_waddr (ws_csr_waddr ),
.es_csr_raddr (es_csr_raddr ),
.es_csr_rdata_sel (es_csr_rdata_sel )
);
assign es_csr_rdata_final = ({`ysyx_040991_DATA_WIDTH{es_csr_rdata_sel[0]}} & es_csr_rdata )
| ({`ysyx_040991_DATA_WIDTH{es_csr_rdata_sel[1]}} & ms_csr_wdata )
| ({`ysyx_040991_DATA_WIDTH{es_csr_rdata_sel[2]}} & ws_csr_wdata );
ysyx_040991_alu #(
.ysyx_040991_DATA_WIDTH (`ysyx_040991_DATA_WIDTH ),
.ALU_WIDTH (11 )
) u_alu (
.alu_src1 (es_alu_src1 ),
.alu_src2 (es_alu_src2 ),
.word_sel (es_word_op ),
.alu_op (es_alu_op ),
.alu_result (es_alu_result )
);
// data cache write signals
assign dcache_valid = es_data_ram_en && es_valid && !es_is_exception && !(ws_flush || ws_flush_r) && !ms_is_exception; // do not store when ms or ws is exception
assign dcache_op = es_data_ram_wen;
assign {dcache_tag, dcache_index, dcache_offset} = es_alu_result[31:0];
assign dcache_wstrb = ({8{es_save_op[3]}} & (({8{dcache_offset[2:0]==3'b000}} & 8'b1 ) // inst_sb
| ({8{dcache_offset[2:0]==3'b001}} & 8'b10 )
| ({8{dcache_offset[2:0]==3'b010}} & 8'b100 )
| ({8{dcache_offset[2:0]==3'b011}} & 8'b1000 )
| ({8{dcache_offset[2:0]==3'b100}} & 8'b10000 )
| ({8{dcache_offset[2:0]==3'b101}} & 8'b100000 )
| ({8{dcache_offset[2:0]==3'b110}} & 8'b1000000 )
| ({8{dcache_offset[2:0]==3'b111}} & 8'b10000000 )))
// inst_sh
| ({8{es_save_op[2]}} & (({8{dcache_offset[2:1]==2'b00 }} & 8'b11 )
| ({8{dcache_offset[2:1]==2'b01 }} & 8'b1100 )
| ({8{dcache_offset[2:1]==2'b10 }} & 8'b110000 )
| ({8{dcache_offset[2:1]==2'b11 }} & 8'b11000000 )))
// inst_sw
| ({8{es_save_op[1]}} & (({8{dcache_offset[2] == 1'b0 }} & 8'b1111 )
| ({8{dcache_offset[2] == 1'b1 }} & 8'b11110000 )))
// inst_sd
| ({8{es_save_op[0]}} & 8'b11111111);
assign dcache_wdata = ({`ysyx_040991_DATA_WIDTH{es_save_op[3]}} & {8{es_rs2_data[7:0]}}) // inst_sb
| ({`ysyx_040991_DATA_WIDTH{es_save_op[2]}} & {4{es_rs2_data[15:0]}}) // inst_sh
| ({`ysyx_040991_DATA_WIDTH{es_save_op[1]}} & {2{es_rs2_data[31:0]}}) // inst_sw
| ({`ysyx_040991_DATA_WIDTH{es_save_op[0]}} & es_rs2_data);
assign es_branch_bus = {es_jalr_en && es_valid, es_alu_result};
assign es_fence = es_fence_i;
// exception
wire es_exception_en;
wire [5:0] es_exception_next;
assign es_exception_en = |es_exception_next[5:4];
assign es_exception_next[5:4] = 2'b0;
assign es_exception_next[3:0] = 4'b0;
assign es_to_ms_exception = es_exception_en ? es_exception_next : es_exception_curr;
// debug infomation
assign dcache_uncache = ((es_alu_result & 64'hf000_0000) != 64'h8000_0000) && es_data_ram_en && es_valid;
endmodule
module ysyx_040991_forwarding_unit(
// exe to id
input es_rd_wen,
input [4:0] es_rd_addr,
// mem to id
input ms_rd_wen,
input [4:0] ms_rd_addr,
// wb to id
input ws_rd_wen,
input [4:0] ws_rd_addr,
// id signals
input [4:0] ds_rs1_addr,
input [4:0] ds_rs2_addr,
output [3:0] ds_rs1_forward_sel,
output [3:0] ds_rs2_forward_sel
);
wire es_rd_bypass1;
wire ms_rd_bypass1;
wire ws_rd_bypass1;
assign es_rd_bypass1 = es_rd_wen && |es_rd_addr && (es_rd_addr == ds_rs1_addr);
assign ms_rd_bypass1 = ms_rd_wen && |ms_rd_addr && (ms_rd_addr == ds_rs1_addr);
assign ws_rd_bypass1 = ws_rd_wen && |ws_rd_addr && (ws_rd_addr == ds_rs1_addr);
// [0] rf_rdata1
assign ds_rs1_forward_sel[0] = ~es_rd_bypass1
&& ~ms_rd_bypass1
&& ~ws_rd_bypass1;
// [1] es result1
assign ds_rs1_forward_sel[1] = es_rd_bypass1;
// [2] ms result1
assign ds_rs1_forward_sel[2] = ~es_rd_bypass1
&& ms_rd_bypass1;
// [3] ws result1
assign ds_rs1_forward_sel[3] = ~es_rd_bypass1
&& ~ms_rd_bypass1
&& ws_rd_bypass1;
wire es_rd_bypass2;
wire ms_rd_bypass2;
wire ws_rd_bypass2;
assign es_rd_bypass2 = es_rd_wen && |es_rd_addr && (es_rd_addr == ds_rs2_addr);
assign ms_rd_bypass2 = ms_rd_wen && |ms_rd_addr && (ms_rd_addr == ds_rs2_addr);
assign ws_rd_bypass2 = ws_rd_wen && |ws_rd_addr && (ws_rd_addr == ds_rs2_addr);
// [0] rf_rdata2
assign ds_rs2_forward_sel[0] = ~es_rd_bypass2
&& ~ms_rd_bypass2
&& ~ws_rd_bypass2;
// [1] es result2
assign ds_rs2_forward_sel[1] = es_rd_bypass2;
// [2] ms result2
assign ds_rs2_forward_sel[2] = ~es_rd_bypass2
&& ms_rd_bypass2;
// [3] ws result2
assign ds_rs2_forward_sel[3] = ~es_rd_bypass2
&& ~ms_rd_bypass2
&& ws_rd_bypass2;
endmodule
module ysyx_040991_id_stage(
input clk ,
input rst ,
input interrupt_taken,
//allowin
input es_allowin ,
output ds_allowin ,
//from fs
input fs_to_ds_valid,
input [`ysyx_040991_FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus ,
input [`ysyx_040991_EXCEPTION_WD-1:0] fs_to_ds_exception,
//to es
output ds_to_es_valid,
output [`ysyx_040991_DS_TO_ES_BUS_WD -1:0] ds_to_es_bus ,
output [`ysyx_040991_EXCEPTION_WD-1:0] ds_to_es_exception,
//to ctrl
output [`ysyx_040991_BR_BUS_WD :0] ds_branch_bus,
input ws_flush,
//to rf: for write back
input [`ysyx_040991_WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus,
// forwarding signals
input [`ysyx_040991_ES_FORWARDING_BUS_WD -1:0] es_forwarding_bus,
input [`ysyx_040991_MS_FORWARDING_BUS_WD -1:0] ms_forwarding_bus,
input [`ysyx_040991_WS_FORWARDING_BUS_WD -1:0] ws_forwarding_bus
// from csr
// input [1:0] priv_i
);
reg ds_valid ;
wire ds_ready_go;
reg [`ysyx_040991_FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus_r;
wire [31:0] ds_inst;
wire [`ysyx_040991_VADDR_WIDTH-1:0] ds_pc;
assign {
ds_inst,
ds_pc
} = fs_to_ds_bus_r;
wire [5:0] ds_exception_curr;
reg [`ysyx_040991_EXCEPTION_WD-1:0] fs_to_ds_exception_r;
assign ds_exception_curr = fs_to_ds_exception_r;
wire rf_wen ;
wire [ 4:0] rf_waddr;
wire [`ysyx_040991_DATA_WIDTH-1:0] rf_wdata;
assign {
rf_wen ,
rf_waddr ,
rf_wdata
} = ws_to_rf_bus;
wire [10:0] alu_op;
wire [4:0] src1_sel;
wire [4:0] src2_sel;
wire [6:0] load_op;
wire [3:0] save_op;
wire [3:0] mul_op;
wire [3:0] div_op;
wire word_op;
wire [5:0] wb_sel;
wire rd_wen; // ds stage
wire [ 4:0] rf_raddr1;
wire [ 4:0] rf_raddr2;
wire [`ysyx_040991_DATA_WIDTH-1:0] rs1_data;
wire [`ysyx_040991_DATA_WIDTH-1:0] rs2_data;
wire [4:0] rd_addr;
wire [4:0] rs1_addr;
wire [4:0] rs2_addr;
wire data_ram_en;
wire data_ram_wen;
wire [3:0] rs1_forward_sel;
wire [3:0] rs2_forward_sel;
wire es_rd_wen;
wire [4:0] es_rd_addr;
wire [`ysyx_040991_DATA_WIDTH-1:0] es_rd_data;
wire ms_rd_wen;
wire [4:0] ms_rd_addr;
wire [`ysyx_040991_DATA_WIDTH-1:0] ms_rd_data;
wire ws_rd_wen;
wire [4:0] ws_rd_addr;
wire [`ysyx_040991_DATA_WIDTH-1:0] ws_rd_data;
wire es_ds_stall;
wire ms_ds_stall;
wire ds_stall;
wire fence;
assign {
es_ds_stall,
es_rd_wen,
es_rd_addr,
es_rd_data
} = es_forwarding_bus;
assign {
ms_ds_stall,
ms_rd_wen,
ms_rd_addr,
ms_rd_data
} = ms_forwarding_bus;
assign {
ws_rd_wen,
ws_rd_addr,
ws_rd_data
} = ws_forwarding_bus;
wire jalr_en;
wire csr_wen;
assign ds_to_es_bus = {
fence ,
alu_op ,
src1_sel ,
src2_sel ,
load_op ,
save_op ,
mul_op ,
div_op ,
word_op ,
wb_sel ,
rd_wen ,
data_ram_en ,
data_ram_wen,
rs1_data ,
rs2_data ,
rd_addr ,
jalr_en ,
csr_wen ,
ds_stall ,
ds_pc ,
ds_inst
};
reg ws_flush_r;
always @(posedge clk) begin
if (rst) begin
ws_flush_r <= 1'b0;
end else if (ws_flush) begin
ws_flush_r <= 1'b1;
end else if (fs_to_ds_valid & ds_allowin) begin
ws_flush_r <= 1'b0;
end
end
assign ds_ready_go = !(ms_ds_stall && (ms_rd_addr == rs1_addr || ms_rd_addr == rs2_addr))
&& !(es_ds_stall && (es_rd_addr == rs1_addr || es_rd_addr == rs2_addr)); // stall when load mul div in exe stage
assign ds_allowin = !ds_valid || ds_ready_go && es_allowin;
assign ds_to_es_valid = ds_valid && ds_ready_go && !(ws_flush || ws_flush_r);
always @(posedge clk) begin
if (rst) begin
ds_valid <= 1'b0;
end
else if (ds_allowin) begin
ds_valid <= fs_to_ds_valid;
end
if (fs_to_ds_valid && ds_allowin) begin
fs_to_ds_bus_r <= fs_to_ds_bus;
fs_to_ds_exception_r <= fs_to_ds_exception;
end
end
wire [2:0] funct3;
wire [6:0] opcode;
wire [6:0] funct7;
assign funct3 = ds_inst[14:12];
assign opcode = ds_inst[6:0];
assign funct7 = ds_inst[31:25];
assign rd_addr = ds_inst[11:7];
assign rs1_addr = ds_inst[19:15];
assign rs2_addr = ds_inst[24:20];
wire [7:0] funct3_d;
wire [127:0] opcode_d;
wire [127:0] funct7_d;
ysyx_040991_decoder_3_8 u_dec0(.in(funct3), .out(funct3_d));
ysyx_040991_decoder_7_128 u_dec1(.in(opcode), .out(opcode_d));
ysyx_040991_decoder_7_128 u_dec2(.in(funct7), .out(funct7_d));
// RV32I
// U type
wire inst_lui, inst_auipc;
assign inst_lui = opcode_d[7'b0110111];
assign inst_auipc = opcode_d[7'b0010111];
// J type & I type
wire inst_jal, inst_jalr;
assign inst_jal = opcode_d[7'b1101111];
assign inst_jalr = opcode_d[7'b1100111] & funct3_d[3'b000];
// B type
wire inst_beq, inst_bne, inst_blt, inst_bge, inst_bltu, inst_bgeu;
assign inst_beq = opcode_d[7'b1100011] & funct3_d[3'b000];
assign inst_bne = opcode_d[7'b1100011] & funct3_d[3'b001];
assign inst_blt = opcode_d[7'b1100011] & funct3_d[3'b100];
assign inst_bge = opcode_d[7'b1100011] & funct3_d[3'b101];
assign inst_bltu = opcode_d[7'b1100011] & funct3_d[3'b110];
assign inst_bgeu = opcode_d[7'b1100011] & funct3_d[3'b111];
// I type
wire inst_lb, inst_lh, inst_lw, inst_lbu, inst_lhu;
assign inst_lb = opcode_d[7'b0000011] & funct3_d[3'b000];
assign inst_lh = opcode_d[7'b0000011] & funct3_d[3'b001];
assign inst_lw = opcode_d[7'b0000011] & funct3_d[3'b010];
assign inst_lbu = opcode_d[7'b0000011] & funct3_d[3'b100];
assign inst_lhu = opcode_d[7'b0000011] & funct3_d[3'b101];
// S type
wire inst_sb, inst_sh, inst_sw;
assign inst_sb = opcode_d[7'b0100011] & funct3_d[3'b000];
assign inst_sh = opcode_d[7'b0100011] & funct3_d[3'b001];
assign inst_sw = opcode_d[7'b0100011] & funct3_d[3'b010];
// I type
wire inst_addi, inst_slti, inst_sltiu, inst_xori, inst_ori, inst_andi, inst_slli, inst_srli, inst_srai;
assign inst_addi = opcode_d[7'b0010011] & funct3_d[3'b000];
assign inst_slti = opcode_d[7'b0010011] & funct3_d[3'b010];
assign inst_sltiu = opcode_d[7'b0010011] & funct3_d[3'b011];
assign inst_xori = opcode_d[7'b0010011] & funct3_d[3'b100];
assign inst_ori = opcode_d[7'b0010011] & funct3_d[3'b110];
assign inst_andi = opcode_d[7'b0010011] & funct3_d[3'b111];
assign inst_slli = opcode_d[7'b0010011] & funct3_d[3'b001] & ~|ds_inst[31:26]; // shamt[25:20]
assign inst_srli = opcode_d[7'b0010011] & funct3_d[3'b101] & ~|ds_inst[31:26]; // shamt[25:20]
assign inst_srai = opcode_d[7'b0010011] & funct3_d[3'b101] & ~ds_inst[31] & ds_inst[30] & ~|ds_inst[29:26]; // shamt[25:20]
// R type
wire inst_add, inst_sub, inst_sll, inst_slt, inst_sltu, inst_xor, inst_srl, inst_sra, inst_or, inst_and;
assign inst_add = opcode_d[7'b0110011] & funct3_d[3'b000] & funct7_d[7'b0000000];
assign inst_sub = opcode_d[7'b0110011] & funct3_d[3'b000] & funct7_d[7'b0100000];
assign inst_sll = opcode_d[7'b0110011] & funct3_d[3'b001] & funct7_d[7'b0000000];
assign inst_slt = opcode_d[7'b0110011] & funct3_d[3'b010] & funct7_d[7'b0000000];
assign inst_sltu = opcode_d[7'b0110011] & funct3_d[3'b011] & funct7_d[7'b0000000];
assign inst_xor = opcode_d[7'b0110011] & funct3_d[3'b100] & funct7_d[7'b0000000];
assign inst_srl = opcode_d[7'b0110011] & funct3_d[3'b101] & funct7_d[7'b0000000];
assign inst_sra = opcode_d[7'b0110011] & funct3_d[3'b101] & funct7_d[7'b0100000];
assign inst_or = opcode_d[7'b0110011] & funct3_d[3'b110] & funct7_d[7'b0000000];
assign inst_and = opcode_d[7'b0110011] & funct3_d[3'b111] & funct7_d[7'b0000000];
// csr instructions I type
wire inst_csrrw, inst_csrrs, inst_csrrc, inst_csrrwi, inst_csrrsi, inst_csrrci;
assign inst_csrrw = opcode_d[7'b1110011] & funct3_d[3'b001];
assign inst_csrrs = opcode_d[7'b1110011] & funct3_d[3'b010];
assign inst_csrrc = opcode_d[7'b1110011] & funct3_d[3'b011];
assign inst_csrrwi = opcode_d[7'b1110011] & funct3_d[3'b101];
assign inst_csrrsi = opcode_d[7'b1110011] & funct3_d[3'b110];
assign inst_csrrci = opcode_d[7'b1110011] & funct3_d[3'b111];
// others
wire inst_ebreak, inst_ecall, inst_mret;
assign inst_ebreak = opcode_d[7'b1110011] & ~|ds_inst[31:21] & ds_inst[20] & ~|ds_inst[19:7];
assign inst_ecall = opcode_d[7'b1110011] & ~|ds_inst[31:7];
assign inst_mret = opcode_d[7'b1110011] & funct7_d[7'b0011000] & ~|ds_inst[20:7] & ds_inst[21] & ~|ds_inst[24:22];
wire inst_fence_i;
assign inst_fence_i = opcode_d[7'b0001111] & ~|ds_inst[31:13] & ds_inst[12] & ~|ds_inst[11:7];
// RV64I
// S type
wire inst_sd;
assign inst_sd = opcode_d[7'b0100011] & funct3_d[3'b011];
// I type
wire inst_ld, inst_lwu;
assign inst_ld = opcode_d[7'b0000011] & funct3_d[3'b011];
assign inst_lwu = opcode_d[7'b0000011] & funct3_d[3'b110];
wire inst_addiw, inst_slliw, inst_srliw, inst_sraiw;
assign inst_addiw = opcode_d[7'b0011011] & funct3_d[3'b000];
assign inst_slliw = opcode_d[7'b0011011] & funct3_d[3'b001] & funct7_d[7'b0000000]; // shamt[24:20]
assign inst_srliw = opcode_d[7'b0011011] & funct3_d[3'b101] & funct7_d[7'b0000000]; // shamt[24:20]
assign inst_sraiw = opcode_d[7'b0011011] & funct3_d[3'b101] & funct7_d[7'b0100000]; // shamt[24:20]
// R type
wire inst_addw, inst_subw, inst_sllw, inst_srlw, inst_sraw;
assign inst_addw = opcode_d[7'b0111011] & funct3_d[3'b000] & funct7_d[7'b0000000];
assign inst_subw = opcode_d[7'b0111011] & funct3_d[3'b000] & funct7_d[7'b0100000];
assign inst_sllw = opcode_d[7'b0111011] & funct3_d[3'b001] & funct7_d[7'b0000000];
assign inst_srlw = opcode_d[7'b0111011] & funct3_d[3'b101] & funct7_d[7'b0000000];
assign inst_sraw = opcode_d[7'b0111011] & funct3_d[3'b101] & funct7_d[7'b0100000];
// RV32M
// R type
wire inst_mul, inst_mulh, inst_mulhsu, inst_mulhu, inst_div, inst_divu, inst_rem, inst_remu;
assign inst_mul = opcode_d[7'b0110011] & funct3_d[3'b000] & funct7_d[7'b0000001];
assign inst_mulh = opcode_d[7'b0110011] & funct3_d[3'b001] & funct7_d[7'b0000001];
assign inst_mulhsu = opcode_d[7'b0110011] & funct3_d[3'b010] & funct7_d[7'b0000001];
assign inst_mulhu = opcode_d[7'b0110011] & funct3_d[3'b011] & funct7_d[7'b0000001];
assign inst_div = opcode_d[7'b0110011] & funct3_d[3'b100] & funct7_d[7'b0000001];
assign inst_divu = opcode_d[7'b0110011] & funct3_d[3'b101] & funct7_d[7'b0000001];
assign inst_rem = opcode_d[7'b0110011] & funct3_d[3'b110] & funct7_d[7'b0000001];
assign inst_remu = opcode_d[7'b0110011] & funct3_d[3'b111] & funct7_d[7'b0000001];
// RV64M
// R type
wire inst_mulw, inst_divw, inst_divuw, inst_remw, inst_remuw;
assign inst_mulw = opcode_d[7'b0111011] & funct3_d[3'b000] & funct7_d[7'b0000001];
assign inst_divw = opcode_d[7'b0111011] & funct3_d[3'b100] & funct7_d[7'b0000001];
assign inst_divuw = opcode_d[7'b0111011] & funct3_d[3'b101] & funct7_d[7'b0000001];
assign inst_remw = opcode_d[7'b0111011] & funct3_d[3'b110] & funct7_d[7'b0000001];
assign inst_remuw = opcode_d[7'b0111011] & funct3_d[3'b111] & funct7_d[7'b0000001];
// alu_op [0]add [1]sub [2]slt [3]sltu [4]and [5]nop [6]or [7]xor [8]sll [9]srl [10]sra
assign alu_op[ 0] = inst_add | inst_addi | inst_addw | inst_addiw
| inst_lb | inst_lh | inst_lw | inst_lbu | inst_lhu | inst_lwu | inst_ld
| inst_sb | inst_sh | inst_sw | inst_sd
| inst_jalr | inst_auipc;
assign alu_op[ 1] = inst_sub | inst_subw;
assign alu_op[ 2] = inst_slt | inst_slti;
assign alu_op[ 3] = inst_sltu | inst_sltiu;
assign alu_op[ 4] = inst_and | inst_andi | inst_csrrc | inst_csrrci;
assign alu_op[ 5] = inst_lui | inst_csrrw | inst_csrrwi;
assign alu_op[ 6] = inst_or | inst_ori | inst_csrrs | inst_csrrsi;
assign alu_op[ 7] = inst_xor | inst_xori;
assign alu_op[ 8] = inst_sll | inst_slli | inst_sllw | inst_slliw;
assign alu_op[ 9] = inst_srl | inst_srli | inst_srlw | inst_srliw;
assign alu_op[10] = inst_sra | inst_srai | inst_sraw | inst_sraiw;
// src1_sel [4]~z_imm [3]~reg1 [2]z_imm [1]u_imm [0]reg1
assign src1_sel[4] = inst_csrrci;
assign src1_sel[3] = inst_csrrc;
assign src1_sel[2] = inst_csrrwi | inst_csrrsi;
assign src1_sel[1] = inst_lui | inst_auipc;
assign src1_sel[0] = inst_lb | inst_lh | inst_lw | inst_lbu | inst_lhu | inst_lwu | inst_ld
| inst_sb | inst_sh | inst_sw | inst_sd
| inst_jalr
| inst_addi | inst_slti | inst_sltiu | inst_xori | inst_ori | inst_andi | inst_slli | inst_srli | inst_srai
| inst_add | inst_sub | inst_sll | inst_slt | inst_sltu | inst_xor | inst_srl | inst_sra | inst_or | inst_and
| inst_addw | inst_subw | inst_sllw | inst_srlw | inst_sraw
| inst_addiw | inst_slliw | inst_srliw | inst_sraiw
| inst_mul | inst_mulh | inst_mulhsu | inst_mulhu | inst_div | inst_divu | inst_rem | inst_remu
| inst_mulw | inst_divw | inst_divuw | inst_remw | inst_remuw
| inst_csrrw | inst_csrrs;
// src2_sel [4]csr_rdata [3]reg2 [2]s_imm [1]i_imm [0]pc
assign src2_sel[4] = inst_csrrs | inst_csrrsi | inst_csrrc | inst_csrrci;
assign src2_sel[3] = inst_add | inst_sub | inst_sll | inst_slt | inst_sltu | inst_xor | inst_srl | inst_sra | inst_or | inst_and
| inst_addw | inst_subw | inst_sllw | inst_srlw | inst_sraw
| inst_mul | inst_mulh | inst_mulhsu | inst_mulhu | inst_div | inst_divu | inst_rem | inst_remu
| inst_mulw | inst_divw | inst_divuw | inst_remw | inst_remuw;
assign src2_sel[2] = inst_sb | inst_sh | inst_sw | inst_sd;
assign src2_sel[1] = inst_lb | inst_lh | inst_lw | inst_lbu | inst_lhu | inst_lwu | inst_ld
| inst_addi | inst_slti | inst_sltiu | inst_xori | inst_ori | inst_andi | inst_slli | inst_srli | inst_srai
| inst_addiw | inst_slliw | inst_srliw | inst_sraiw
| inst_jalr;
assign src2_sel[0] = inst_auipc;
// wb_sel[5]div result [4]mul result [3]data ram dout [2]alu result [1]snpc [0]csr_rdata
assign wb_sel[5] = inst_div | inst_divu | inst_rem | inst_remu | inst_divw | inst_divuw | inst_remw | inst_remuw;
assign wb_sel[4] = inst_mul | inst_mulh | inst_mulhsu | inst_mulhu | inst_mulw;
assign wb_sel[3] = inst_lb | inst_lh | inst_lw | inst_lbu | inst_lhu | inst_lwu | inst_ld;
assign wb_sel[2] = inst_lui | inst_auipc
| inst_addi | inst_slti | inst_sltiu | inst_xori | inst_ori | inst_andi | inst_slli | inst_srli | inst_srai
| inst_add | inst_sub | inst_sll | inst_slt | inst_sltu | inst_xor | inst_srl | inst_sra | inst_or | inst_and
| inst_addw | inst_subw | inst_sllw | inst_srlw | inst_sraw
| inst_addiw | inst_slliw | inst_srliw | inst_sraiw;
assign wb_sel[1] = inst_jal | inst_jalr;
assign wb_sel[0] = inst_csrrw | inst_csrrs | inst_csrrc | inst_csrrwi | inst_csrrsi | inst_csrrci;
assign data_ram_en = inst_lb | inst_lh | inst_lw | inst_lbu | inst_lhu | inst_lwu | inst_ld
| inst_sb | inst_sh | inst_sw | inst_sd;
assign data_ram_wen = inst_sb | inst_sh | inst_sw | inst_sd;
assign word_op = inst_addw | inst_subw | inst_sllw | inst_srlw | inst_sraw
| inst_addiw | inst_slliw | inst_srliw | inst_sraiw
| inst_mulw | inst_divw | inst_divuw | inst_remw | inst_remuw;
assign load_op[6] = inst_lb; // 8bit sign extend
assign load_op[5] = inst_lh; // 16bit sign extend
assign load_op[4] = inst_lw; // 32bit sign extend
assign load_op[3] = inst_ld; // 64bit
assign load_op[2] = inst_lbu; // 8bit zero extend
assign load_op[1] = inst_lhu; // 16bit zero extend
assign load_op[0] = inst_lwu; // 32bit zero extend
assign save_op[3] = inst_sb; // 8bit
assign save_op[2] = inst_sh; // 16bit
assign save_op[1] = inst_sw; // 32bit
assign save_op[0] = inst_sd; // 64bit
assign mul_op[3] = inst_mul | inst_mulw;
assign mul_op[2] = inst_mulh;
assign mul_op[1] = inst_mulhsu;
assign mul_op[0] = inst_mulhu;
assign div_op[3] = inst_div | inst_divw;
assign div_op[2] = inst_divu | inst_divuw;
assign div_op[1] = inst_rem | inst_remw;
assign div_op[0] = inst_remu | inst_remuw;
assign rd_wen = inst_addi | inst_slti | inst_sltiu | inst_xori | inst_ori | inst_andi | inst_slli | inst_srli | inst_srai
| inst_add | inst_sub | inst_sll | inst_slt | inst_sltu | inst_xor | inst_srl | inst_sra | inst_or | inst_and
| inst_addw | inst_subw | inst_sllw | inst_srlw | inst_sraw
| inst_addiw | inst_slliw | inst_srliw | inst_sraiw
| inst_lb | inst_lh | inst_lw | inst_lbu | inst_lhu | inst_lwu | inst_ld
| inst_jal | inst_jalr
| inst_lui | inst_auipc
| inst_mul | inst_mulh | inst_mulhsu | inst_mulhu | inst_div | inst_divu | inst_rem | inst_remu
| inst_mulw | inst_divw | inst_divuw | inst_remw | inst_remuw
| inst_csrrw | inst_csrrs | inst_csrrc | inst_csrrwi | inst_csrrsi | inst_csrrci;
// id stage stall
assign ds_stall = inst_lb | inst_lh | inst_lw | inst_lbu | inst_lhu | inst_lwu | inst_ld
| inst_mul | inst_mulh | inst_mulhsu | inst_mulhu | inst_div | inst_divu | inst_rem | inst_remu
| inst_mulw | inst_divw | inst_divuw | inst_remw | inst_remuw;
// fence.i instruction
assign fence = inst_fence_i;
assign rf_raddr1 = rs1_addr;
assign rf_raddr2 = rs2_addr;
wire [`ysyx_040991_DATA_WIDTH-1:0] rf_rdata1;
wire [`ysyx_040991_DATA_WIDTH-1:0] rf_rdata2;
assign rs1_data = ({64{rs1_forward_sel[0]}} & rf_rdata1)
| ({64{rs1_forward_sel[1]}} & es_rd_data)
| ({64{rs1_forward_sel[2]}} & ms_rd_data)
| ({64{rs1_forward_sel[3]}} & ws_rd_data);
assign rs2_data = ({64{rs2_forward_sel[0]}} & rf_rdata2)
| ({64{rs2_forward_sel[1]}} & es_rd_data)
| ({64{rs2_forward_sel[2]}} & ms_rd_data)
| ({64{rs2_forward_sel[3]}} & ws_rd_data);
ysyx_040991_RegisterFile #(
.ysyx_040991_DATA_WIDTH(`ysyx_040991_DATA_WIDTH)
) regfile (
.clk(clk),
.raddr1(rf_raddr1),
.raddr2(rf_raddr2),
.wb_data(rf_wdata),
.wb_addr(rf_waddr),
.wen(rf_wen),
.rdata1(rf_rdata1),
.rdata2(rf_rdata2)
);
wire br_eq, br_lt, br_ltu;
ysyx_040991_BranchCondGen #(
.ysyx_040991_DATA_WIDTH(`ysyx_040991_DATA_WIDTH)
) u_br_gen (
.reg1(rs1_data),
.reg2(rs2_data),
.br_eq(br_eq),
.br_lt(br_lt),
.br_ltu(br_ltu)
);
wire branch_sel;
assign branch_sel = (inst_beq & br_eq )
| (inst_bne & !br_eq )
| (inst_blt & br_lt )
| (inst_bge & !br_lt )
| (inst_bltu & br_ltu )
| (inst_bgeu & !br_ltu );
wire [`ysyx_040991_DATA_WIDTH-1:0] b_imm;
wire [`ysyx_040991_DATA_WIDTH-1:0] j_imm;
assign j_imm = {{43{ds_inst[31]}}, ds_inst[31], ds_inst[19:12], ds_inst[20], ds_inst[30:21], 1'b0};
assign b_imm = {{51{ds_inst[31]}}, ds_inst[31], ds_inst[7], ds_inst[30:25], ds_inst[11:8], 1'b0};
wire [`ysyx_040991_VADDR_WIDTH-1:0] br_j_pc;
wire br_j_en;
assign br_j_pc = ds_pc + (({64{inst_jal}} & j_imm) // jal pc
| ({64{branch_sel}} & b_imm)); // branch pc
assign br_j_en = (inst_jal || branch_sel) && ds_valid;
assign jalr_en = inst_jalr; // to exe stage
wire br_stall;
assign br_stall = (inst_beq | inst_bne | inst_blt| inst_bltu | inst_bge | inst_bgeu | inst_jal) & !ds_ready_go;
assign ds_branch_bus = {br_stall, br_j_en, br_j_pc};
// csr signals
assign csr_wen = inst_csrrw | inst_csrrs | inst_csrrc | inst_csrrwi | inst_csrrsi | inst_csrrci;
wire ds_exception_en;
wire [5:0] ds_exception_next;
assign ds_exception_en = |ds_exception_next[5:4];
assign ds_exception_next[5:4] = ({2{interrupt_taken }} & `ysyx_040991_EXCEPTION_INTERRUPT) // interrupt
| ({2{inst_ebreak | inst_ecall}} & `ysyx_040991_EXCEPTION_EXCEPTION) // exception
| ({2{inst_mret }} & `ysyx_040991_EXCEPTION_ERET); // ret
assign ds_exception_next[3:0] = ({4{interrupt_taken }} & {`ysyx_040991_IRQ_M_TIMER} ) // interrupt only tmier interrupt
| ({4{inst_ebreak }} & `ysyx_040991_EXCEPTION_BREAKPOINT ) // breakpoint
| ({4{inst_ecall }} & `ysyx_040991_EXCEPTION_ECALL_M ) // ecall
| ({4{inst_mret }} & {2'b0, `ysyx_040991_PRIV_MACHINE} ); // ret
assign ds_to_es_exception = ds_exception_en ? ds_exception_next : ds_exception_curr;
// forwarding logic
ysyx_040991_forwarding_unit u_forward (
.es_rd_wen(es_rd_wen),
.es_rd_addr(es_rd_addr),
.ms_rd_wen(ms_rd_wen),
.ms_rd_addr(ms_rd_addr),
.ws_rd_wen(ws_rd_wen),
.ws_rd_addr(ws_rd_addr),
.ds_rs1_addr(rs1_addr),
.ds_rs2_addr(rs2_addr),
.ds_rs1_forward_sel(rs1_forward_sel),
.ds_rs2_forward_sel(rs2_forward_sel)
);
endmodule
module ysyx_040991_if_stage (
input clk ,
input rst ,
//allowin
input ds_allowin ,
// from ctrl branch bus
input [`ysyx_040991_BR_BUS_WD :0] br_bus ,
input ws_flush,
//to ds
output fs_to_ds_valid ,
output [`ysyx_040991_FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus ,
output [`ysyx_040991_EXCEPTION_WD-1:0] fs_to_ds_exception,
// icache ports
output icache_valid ,
output icache_uncache ,
output icache_op , // 0: read only
output [`ysyx_040991_CACHE_INDEX_WD -1:0] icache_index ,
output [`ysyx_040991_CACHE_TAG_WD -1:0] icache_tag ,
output [`ysyx_040991_CACHE_OFFSET_WD -1:0] icache_offset ,
input icache_addr_ok ,
input icache_data_ok ,
input [63:0] icache_rdata ,
// from csr
input [`ysyx_040991_VADDR_WIDTH-1:0] csr_branch_pc
);
reg fs_valid;
wire fs_ready_go;
wire fs_allowin;
wire [`ysyx_040991_VADDR_WIDTH-1:0] snpc;
wire [`ysyx_040991_VADDR_WIDTH-1:0] dnpc;
wire br_taken;
wire [`ysyx_040991_VADDR_WIDTH-1:0] br_target;
wire br_stall;
assign {br_stall, br_taken, br_target} = br_bus;
wire [`ysyx_040991_INST_WIDTH-1:0] fs_inst;
reg [`ysyx_040991_VADDR_WIDTH-1:0] fs_pc;
assign fs_to_ds_bus = {
fs_inst,
fs_pc
};
assign icache_op = 1'b0;
wire [31:0] icache_raddr;
assign {icache_tag, icache_index, icache_offset} = icache_raddr;
assign icache_raddr = dnpc[31:0];
assign icache_uncache = icache_raddr[31] ? 1'b0 : 1'b1;
assign icache_valid = fs_allowin && !rst;
wire pfs_ready_go;
wire pfs_to_fs_valid;
reg ws_flush_r;
reg [63:0] csr_branch_pc_r;
reg br_taken_r;
reg [63:0] br_target_r;
assign pfs_ready_go = icache_valid && icache_addr_ok;
assign pfs_to_fs_valid = pfs_ready_go;
always @(posedge clk) begin
if(rst) begin
br_taken_r <= 1'b0;
br_target_r <= 64'b0;
end
else if(icache_addr_ok && fs_allowin)begin
br_taken_r <= 1'b0;
br_target_r <= 64'b0;
end
else if(br_taken && !br_stall) begin
br_taken_r <= 1'b1;
br_target_r <= br_target;
end
end
always @(posedge clk) begin
if(rst) begin
ws_flush_r <= 1'b0;
csr_branch_pc_r <= 64'b0;
end
else if(ws_flush) begin
ws_flush_r <= 1'b1;
csr_branch_pc_r <= csr_branch_pc;
end
else if(icache_addr_ok && fs_allowin)begin
ws_flush_r <= 1'b0;
csr_branch_pc_r <= 64'b0;
end
end
assign snpc = fs_pc + 64'h4;
assign dnpc = ws_flush ? csr_branch_pc :
ws_flush_r ? csr_branch_pc_r :
br_taken_r ? br_target_r :
(br_taken && !br_stall) ? br_target :
snpc;
reg fs_inst_valid;
reg [63:0] fs_inst_buff;
reg fs_inst_cancel;
always @(posedge clk ) begin
if(rst) begin
fs_inst_cancel <= 1'b0;
end
else if(!fs_allowin && !fs_ready_go && ((ws_flush) ||( br_taken && ~br_stall))) begin
fs_inst_cancel <= 1'b1;
end
else if(icache_data_ok) begin
fs_inst_cancel <= 1'b0;
end
end
// IF stage
assign fs_ready_go = fs_inst_valid || (fs_valid && icache_data_ok);
assign fs_allowin = !fs_valid || fs_ready_go && ds_allowin;
assign fs_to_ds_valid = fs_valid && fs_ready_go && !fs_inst_cancel && !(br_taken && !br_stall) && !(ws_flush || ws_flush_r);
always @(posedge clk) begin
if (rst) begin
fs_valid <= 1'b0;
end
else if (fs_allowin) begin
fs_valid <= pfs_to_fs_valid;
end
if (rst) begin
fs_pc <= 64'h2fff_fffc;
end
else if (pfs_to_fs_valid && fs_allowin) begin
fs_pc <= dnpc;
end
end
always @(posedge clk ) begin
if(rst) begin
fs_inst_valid <= 1'b0;
end
else if(!fs_inst_valid && icache_data_ok && !ds_allowin) begin
fs_inst_valid <= 1'b1;
end
else if (ds_allowin) begin
fs_inst_valid <= 1'b0;
end
if (rst) begin
fs_inst_buff <= 64'b0;
end
else if(!fs_inst_valid && icache_data_ok && !ds_allowin) begin
fs_inst_buff <= icache_rdata;
end
end
assign fs_inst = fs_inst_valid ? ((icache_offset[2] == 1'b1) ? fs_inst_buff[31:0] : fs_inst_buff[63:32]):
((icache_offset[2] == 1'b1) ? icache_rdata[31:0] : icache_rdata[63:32]);
// exception detect
wire inst_addr_misaligned;
assign inst_addr_misaligned = fs_pc[1:0] != 2'b00;
wire fs_exception_en;
assign fs_exception_en = inst_addr_misaligned;
wire [5:0] fs_exception;
assign fs_exception[5:4] = fs_exception_en ? `ysyx_040991_EXCEPTION_EXCEPTION : 2'b00;
assign fs_exception[3:0] = {4{inst_addr_misaligned}} & `ysyx_040991_EXCEPTION_INST_ADDR_MISALIGNED;
assign fs_to_ds_exception = fs_exception;
endmodule
module ysyx_040991_mem_stage(
input clk ,
input rst ,
// allowin
input ws_allowin ,
output ms_allowin ,
// from es
input es_to_ms_valid,
input [`ysyx_040991_ES_TO_MS_BUS_WD -1:0] es_to_ms_bus ,
input [`ysyx_040991_EXCEPTION_WD-1:0] es_to_ms_exception,
// to ws
output ms_to_ws_valid,
output [`ysyx_040991_MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus ,
output [`ysyx_040991_EXCEPTION_WD -1:0] ms_to_ws_exception,
// from ctrl
input ws_flush,
output ms_is_exception,
// dache ports
input dcache_data_ok ,
input [63:0] dcache_rdata,
// forwarding bus
output [`ysyx_040991_MS_FORWARDING_BUS_WD -1:0] ms_forwarding_bus,
output [`ysyx_040991_CSR_FORWARDING_BUS_WD -1:0] ms_csr_forwarding_bus,
// multiplier
input [`ysyx_040991_DATA_WIDTH-1:0] ms_mul_result,
// divider
input [`ysyx_040991_DATA_WIDTH-1:0] ms_div_result
);
reg ms_valid;
wire ms_ready_go;
reg [`ysyx_040991_ES_TO_MS_BUS_WD -1:0] es_to_ms_bus_r;
reg [`ysyx_040991_EXCEPTION_WD -1:0] es_to_ms_exception_r;
wire [5:0] ms_wb_sel ;
wire [6:0] ms_load_op ;
wire ms_rd_wen ;
wire [4:0] ms_rd_addr ;
wire [`ysyx_040991_DATA_WIDTH-1:0] ms_alu_result ;
wire [`ysyx_040991_DATA_WIDTH-1:0] ms_csr_rdata_final ;
// wire [`ysyx_040991_DATA_WIDTH-1:0] ms_mul_result ;
// wire [`ysyx_040991_DATA_WIDTH-1:0] ms_div_result ;
wire [`ysyx_040991_VADDR_WIDTH-1:0] ms_pc ;
wire ms_csr_wen;
wire [31:0] ms_inst;
// wire ms_dcache_uncache;
wire ms_data_ram_en;
assign {
// ms_dcache_uncache ,
ms_data_ram_en ,
ms_wb_sel ,
ms_load_op ,
ms_rd_wen ,
ms_rd_addr ,
ms_alu_result ,
ms_csr_rdata_final,
ms_csr_wen ,
ms_pc,
ms_inst
} = es_to_ms_bus_r;
wire [`ysyx_040991_DATA_WIDTH-1:0] load_data;
wire [`ysyx_040991_DATA_WIDTH-1:0] ms_final_result;
assign ms_to_ws_bus = {
// ms_dcache_uncache ,
ms_rd_wen ,
ms_rd_addr ,
ms_final_result ,
ms_alu_result ,
ms_csr_wen ,
ms_pc ,
ms_inst
};
wire [5:0] ms_exception_curr;
assign ms_exception_curr = es_to_ms_exception_r;
assign ms_is_exception = |ms_exception_curr[5:4] && ms_valid;
reg ws_flush_r;
always @(posedge clk) begin
if (rst) begin
ws_flush_r <= 1'b0;
end else if (ws_flush) begin
ws_flush_r <= 1'b1;
end else if (es_to_ms_valid && ms_allowin) begin
ws_flush_r <= 1'b0;
end
end
assign ms_ready_go = ms_data_ram_en ? dcache_data_ok || ms_is_exception || ws_flush || ws_flush_r: 1'b1;
assign ms_allowin = !ms_valid || ms_ready_go && ws_allowin;
assign ms_to_ws_valid = ms_valid && ms_ready_go && !(ws_flush || ws_flush_r);
always @(posedge clk) begin
if (rst) begin
ms_valid <= 1'b0;
end
else if (ms_allowin) begin
ms_valid <= es_to_ms_valid;
end
if (es_to_ms_valid && ms_allowin) begin
es_to_ms_bus_r <= es_to_ms_bus;
es_to_ms_exception_r <= es_to_ms_exception;
end
end
wire [`ysyx_040991_VADDR_WIDTH-1:0] data_ram_addr;
assign data_ram_addr = ms_alu_result;
assign load_data = ({`ysyx_040991_DATA_WIDTH{ms_load_op[6]}} & (({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b000}} & {{56{dcache_rdata[ 7]}}, dcache_rdata[ 7: 0]} ) // inst_lb
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b001}} & {{56{dcache_rdata[15]}}, dcache_rdata[15: 8]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b010}} & {{56{dcache_rdata[23]}}, dcache_rdata[23:16]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b011}} & {{56{dcache_rdata[31]}}, dcache_rdata[31:24]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b100}} & {{56{dcache_rdata[39]}}, dcache_rdata[39:32]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b101}} & {{56{dcache_rdata[47]}}, dcache_rdata[47:40]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b110}} & {{56{dcache_rdata[55]}}, dcache_rdata[55:48]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b111}} & {{56{dcache_rdata[63]}}, dcache_rdata[63:56]} )))
// inst_lh
| ({`ysyx_040991_DATA_WIDTH{ms_load_op[5]}} & (({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:1]==2'b00 }} & {{48{dcache_rdata[15]}}, dcache_rdata[15: 0]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:1]==2'b01 }} & {{48{dcache_rdata[31]}}, dcache_rdata[31:16]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:1]==2'b10 }} & {{48{dcache_rdata[47]}}, dcache_rdata[47:32]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:1]==2'b11 }} & {{48{dcache_rdata[63]}}, dcache_rdata[63:48]} )))
// inst_lw
| ({`ysyx_040991_DATA_WIDTH{ms_load_op[4]}} & (({`ysyx_040991_DATA_WIDTH{data_ram_addr[2] == 1'b0 }} & {{32{dcache_rdata[31]}}, dcache_rdata[31: 0]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2] == 1'b1 }} & {{32{dcache_rdata[63]}}, dcache_rdata[63:32]} )))
// inst_ld
| ({`ysyx_040991_DATA_WIDTH{ms_load_op[3]}} & dcache_rdata)
// inst_lbu
| ({`ysyx_040991_DATA_WIDTH{ms_load_op[2]}} & (({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b000}} & {56'b0, dcache_rdata[ 7: 0]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b001}} & {56'b0, dcache_rdata[15: 8]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b010}} & {56'b0, dcache_rdata[23:16]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b011}} & {56'b0, dcache_rdata[31:24]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b100}} & {56'b0, dcache_rdata[39:32]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b101}} & {56'b0, dcache_rdata[47:40]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b110}} & {56'b0, dcache_rdata[55:48]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:0]==3'b111}} & {56'b0, dcache_rdata[63:56]} )))
// inst_lhu
| ({`ysyx_040991_DATA_WIDTH{ms_load_op[1]}} & (({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:1]==2'b00 }} & {48'b0, dcache_rdata[15: 0]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:1]==2'b01 }} & {48'b0, dcache_rdata[31:16]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:1]==2'b10 }} & {48'b0, dcache_rdata[47:32]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2:1]==2'b11 }} & {48'b0, dcache_rdata[63:48]} )))
// inst_lwu
| ({`ysyx_040991_DATA_WIDTH{ms_load_op[0]}} & (({`ysyx_040991_DATA_WIDTH{data_ram_addr[2] == 1'b0 }} & {32'b0, dcache_rdata[31: 0]} )
|({`ysyx_040991_DATA_WIDTH{data_ram_addr[2] == 1'b1 }} & {32'b0, dcache_rdata[63:32]} )));
assign ms_final_result = ({`ysyx_040991_DATA_WIDTH{ms_wb_sel[0]}} & ms_csr_rdata_final)
| ({`ysyx_040991_DATA_WIDTH{ms_wb_sel[1]}} & ms_pc + 4)
| ({`ysyx_040991_DATA_WIDTH{ms_wb_sel[2]}} & ms_alu_result)
| ({`ysyx_040991_DATA_WIDTH{ms_wb_sel[3]}} & load_data)
| ({`ysyx_040991_DATA_WIDTH{ms_wb_sel[4]}} & ms_mul_result)
| ({`ysyx_040991_DATA_WIDTH{ms_wb_sel[5]}} & ms_div_result);
wire ms_ds_stall;
assign ms_ds_stall = ms_data_ram_en && ms_valid && !ms_to_ws_valid;
assign ms_forwarding_bus = {
ms_ds_stall,
ms_rd_wen && ms_valid && ms_to_ws_valid,//
ms_rd_addr,
ms_final_result
};
assign ms_csr_forwarding_bus = {
ms_csr_wen && ms_valid,
ms_inst[31:20],
ms_alu_result
};
// exception handling
wire ms_exception_en;
wire [5:0] ms_exception_next;
assign ms_exception_en = |ms_exception_next[5:4];
assign ms_exception_next[5:4] = 2'b0;
assign ms_exception_next[3:0] = 4'b0;
assign ms_to_ws_exception = ms_exception_en ? ms_exception_next : ms_exception_curr;
endmodule
module ysyx_040991_multiplier #(
parameter ysyx_040991_DATA_WIDTH = 64
)(
input clk,
input rst,
input [ysyx_040991_DATA_WIDTH-1:0] mul_src1,
input [ysyx_040991_DATA_WIDTH-1:0] mul_src2,
input [3:0] mul_op,
input word_op, // word instructions
output [ysyx_040991_DATA_WIDTH-1:0] mul_wb_result
);
wire op_mul = mul_op[ 3] & ~word_op;
wire op_mulh = mul_op[ 2] & ~word_op;
wire op_mulhsu = mul_op[ 1] & ~word_op;
wire op_mulhu = mul_op[ 0] & ~word_op;
wire op_mulw = mul_op[ 3] & word_op;
reg op_mul_r ;
reg op_mulh_r ;
reg op_mulhsu_r ;
reg op_mulhu_r ;
reg op_mulw_r ;
always @ (posedge clk) begin
if(rst) begin
op_mul_r <= 1'b0;
op_mulh_r <= 1'b0;
op_mulhsu_r <= 1'b0;
op_mulhu_r <= 1'b0;
op_mulw_r <= 1'b0;
end
else begin
op_mul_r <= op_mul ;
op_mulh_r <= op_mulh ;
op_mulhsu_r <= op_mulhsu;
op_mulhu_r <= op_mulhu ;
op_mulw_r <= op_mulw ;
end
end
// radix-4 booth multiplier
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_2x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_3x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_4x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_5x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_6x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_7x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_8x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_nx;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_n2x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_n3x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_n4x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_n5x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_n6x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_n7x;
wire [2*ysyx_040991_DATA_WIDTH+1:0] mul_n8x;
assign mul_x = ({130{op_mul | op_mulh | op_mulhsu | op_mulw}} & {{66{mul_src1[63]}}, mul_src1}) // signed extend multiplier
| ({130{op_mulhu}} & {66'b0, mul_src1}); // zero extend multiplier
assign mul_2x = mul_x << 1;
assign mul_3x = mul_x + mul_2x;
assign mul_4x = mul_x << 2;
assign mul_5x = mul_x + mul_4x;
assign mul_6x = mul_2x + mul_4x;
assign mul_7x = mul_x + mul_2x + mul_4x;
assign mul_8x = mul_x << 3;
assign mul_nx = ~mul_x + 1;
assign mul_n2x = ~mul_2x + 1;
assign mul_n3x = ~mul_3x + 1;
assign mul_n4x = ~mul_4x + 1;
assign mul_n5x = ~mul_5x + 1;
assign mul_n6x = ~mul_6x + 1;
assign mul_n7x = ~mul_7x + 1;
assign mul_n8x = ~mul_8x + 1;
// decode
wire [ysyx_040991_DATA_WIDTH+4:0] mul_y_ext; // 69bit extended multiplier
assign mul_y_ext = ({69{op_mul | op_mulh | op_mulw}} & {{4{mul_src2[63]}}, mul_src2, 1'b0})
| ({69{op_mulhsu | op_mulhu}} & {4'b0, mul_src2, 1'b0});
wire [4:0] mul_y_bits [0:16];
wire [129:0] partial_product [0:16]; // bus [i*2*ysyx_040991_DATA_WIDTH+:2*ysyx_040991_DATA_WIDTH]
genvar i;
generate
for (i=0; i<17; i=i+1) begin
assign mul_y_bits[i] = mul_y_ext[4*i+:5];
assign partial_product[i] = (({130{mul_y_bits[i] == 5'b00000 || mul_y_bits[i] == 5'b11111}} & 130'b0)
| ({130{mul_y_bits[i] == 5'b00001 || mul_y_bits[i] == 5'b00010}} & mul_x)
| ({130{mul_y_bits[i] == 5'b00011 || mul_y_bits[i] == 5'b00100}} & mul_2x)
| ({130{mul_y_bits[i] == 5'b00101 || mul_y_bits[i] == 5'b00110}} & mul_3x)
| ({130{mul_y_bits[i] == 5'b00111 || mul_y_bits[i] == 5'b01000}} & mul_4x)
| ({130{mul_y_bits[i] == 5'b01001 || mul_y_bits[i] == 5'b01010}} & mul_5x)
| ({130{mul_y_bits[i] == 5'b01011 || mul_y_bits[i] == 5'b01100}} & mul_6x)
| ({130{mul_y_bits[i] == 5'b01101 || mul_y_bits[i] == 5'b01110}} & mul_7x)
| ({130{mul_y_bits[i] == 5'b01111}} & mul_8x)
| ({130{mul_y_bits[i] == 5'b10000}} & mul_n8x)
| ({130{mul_y_bits[i] == 5'b10001 || mul_y_bits[i] == 5'b10010}} & mul_n7x)
| ({130{mul_y_bits[i] == 5'b10011 || mul_y_bits[i] == 5'b10100}} & mul_n6x)
| ({130{mul_y_bits[i] == 5'b10101 || mul_y_bits[i] == 5'b10110}} & mul_n5x)
| ({130{mul_y_bits[i] == 5'b10111 || mul_y_bits[i] == 5'b11000}} & mul_n4x)
| ({130{mul_y_bits[i] == 5'b11001 || mul_y_bits[i] == 5'b11010}} & mul_n3x)
| ({130{mul_y_bits[i] == 5'b11011 || mul_y_bits[i] == 5'b11100}} & mul_n2x)
| ({130{mul_y_bits[i] == 5'b11101 || mul_y_bits[i] == 5'b11110}} & mul_nx)) << (4*i);
end
endgenerate
// pipeline
reg [129:0] partial_product_r [0:16];
integer m;
always@(posedge clk) begin
if (rst) begin
for (m=0; m<17; m=m+1) begin
partial_product_r[m] <= 130'b0;
end
end
else begin
for (m=0; m<17; m=m+1) begin
partial_product_r[m] <= partial_product[m];
end
end
end
wire [16:0] partial_product_switch [0:129];
genvar j;
generate
for (j=0; j<130; j=j+1) begin
for (i=0; i<17; i=i+1) begin
assign partial_product_switch[j][i] = partial_product_r[i][j];
end
end
endgenerate
wire [13:0] cout_bus [0:130] /*verilator split_var*/; // cout_bus[2*ysyx_040991_DATA_WIDTH] unused
assign cout_bus[0] = 14'b0;
wire [129:0] c_final_bus;
wire [129:0] s_final_bus;
genvar k;
generate
for (k=0; k<130; k=k+1) begin: wtrees
ysyx_040991_wallace_tree u_wtree(
.din (partial_product_switch[k] ),
.cin (cout_bus[k] ),
.cout (cout_bus[k+1] ),
.c_final (c_final_bus[k] ),
.s_final (s_final_bus[k] )
);
end
endgenerate
wire [130:0] c_s_sum;
wire [127:0] mul_product;
assign c_s_sum = {c_final_bus[128:0], 1'b0} + s_final_bus;
assign mul_product = c_s_sum[127:0];
wire [63:0] mul_result = mul_product[63:0];
wire [63:0] mulh_result = mul_product[127:64];
wire [63:0] mulw_result = {{32{mul_product[31]}}, mul_product[31:0]};
assign mul_wb_result = ({64{op_mul_r }} & mul_result)
| ({64{op_mulh_r }} & mulh_result)
| ({64{op_mulhsu_r }} & mulh_result)
| ({64{op_mulhu_r }} & mulh_result)
| ({64{op_mulw_r }} & mulw_result);
endmodule
module ysyx_040991_npc_core (
input clk,
input rst,
input interrupt_taken,
// to cache
output icache_valid ,
output icache_uncache ,
output icache_op , // 0: read only
output [`ysyx_040991_CACHE_INDEX_WD -1:0] icache_index ,
output [`ysyx_040991_CACHE_TAG_WD -1:0] icache_tag ,
output [`ysyx_040991_CACHE_OFFSET_WD -1:0] icache_offset ,
input icache_addr_ok ,
input icache_data_ok ,
input [63:0] icache_rdata ,
// ports of dcache
output dcache_valid ,
output dcache_uncache ,
output dcache_op , // 0: read, 1: write
output [`ysyx_040991_CACHE_INDEX_WD -1:0] dcache_index ,
output [`ysyx_040991_CACHE_TAG_WD -1:0] dcache_tag ,
output [`ysyx_040991_CACHE_OFFSET_WD -1:0] dcache_offset ,
output [ 7:0] dcache_wstrb ,
output [63:0] dcache_wdata ,
input dcache_addr_ok ,
input dcache_data_ok ,
input [63:0] dcache_rdata ,
output es_fence,
input es_fence_complete
);
/* verilator lint_off UNOPTFLAT */
// IF stage
wire ds_allowin;
wire [`ysyx_040991_BR_BUS_WD :0] br_bus;
wire fs_to_ds_valid;
wire [`ysyx_040991_FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus;
wire [`ysyx_040991_EXCEPTION_WD -1:0] fs_to_ds_exception;
wire [`ysyx_040991_VADDR_WIDTH -1:0] csr_branch_pc;
wire ws_is_eret;
wire ws_is_exception;
wire ms_is_exception;
wire ws_flush;
assign ws_flush = ws_is_eret || ws_is_exception;
ysyx_040991_if_stage u_fs (
.clk (clk ),
.rst (rst ),
// allowin
.ds_allowin (ds_allowin ),
// br_bus
.br_bus (br_bus ),
.ws_flush (ws_flush ),
// to ds
.fs_to_ds_valid (fs_to_ds_valid ),
.fs_to_ds_bus (fs_to_ds_bus ),
.fs_to_ds_exception (fs_to_ds_exception ),
// icache ports
.icache_valid (icache_valid ),
.icache_uncache (icache_uncache ),
.icache_op (icache_op ),
.icache_index (icache_index ),
.icache_tag (icache_tag ),
.icache_offset (icache_offset ),
.icache_addr_ok (icache_addr_ok ),
.icache_data_ok (icache_data_ok ),
.icache_rdata (icache_rdata ),
// from csr
.csr_branch_pc (csr_branch_pc )
);
// id_stage
wire es_allowin;
wire ds_to_es_valid;
wire [`ysyx_040991_DS_TO_ES_BUS_WD -1:0] ds_to_es_bus;
wire [`ysyx_040991_EXCEPTION_WD -1:0] ds_to_es_exception;
wire [`ysyx_040991_WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus;
wire [`ysyx_040991_ES_FORWARDING_BUS_WD -1:0] es_forwarding_bus;
wire [`ysyx_040991_MS_FORWARDING_BUS_WD -1:0] ms_forwarding_bus;
wire [`ysyx_040991_WS_FORWARDING_BUS_WD -1:0] ws_forwarding_bus;
wire [`ysyx_040991_BR_BUS_WD :0] ds_branch_bus;
wire timer_interrupt_en;
ysyx_040991_id_stage u_ds (
.clk(clk),
.rst(rst),
// interrupt
.interrupt_taken(timer_interrupt_en),
// allowin
.es_allowin(es_allowin),
.ds_allowin(ds_allowin),
// from fs
.fs_to_ds_valid(fs_to_ds_valid),
.fs_to_ds_bus(fs_to_ds_bus),
.fs_to_ds_exception(fs_to_ds_exception),
// to es
.ds_to_es_valid(ds_to_es_valid),
.ds_to_es_bus(ds_to_es_bus),
.ds_to_es_exception(ds_to_es_exception),
// to from ctrl
.ds_branch_bus(ds_branch_bus),
.ws_flush (ws_flush ),
// to rf: from wb stage
.ws_to_rf_bus(ws_to_rf_bus),
// forwarding bus
.es_forwarding_bus(es_forwarding_bus),
.ms_forwarding_bus(ms_forwarding_bus),
.ws_forwarding_bus(ws_forwarding_bus)
);
// exe_stage
wire ms_allowin;
wire es_to_ms_valid;
wire [`ysyx_040991_ES_TO_MS_BUS_WD -1:0] es_to_ms_bus;
wire [`ysyx_040991_EXCEPTION_WD -1:0] es_to_ms_exception;
wire ds_to_es_hold;
wire [`ysyx_040991_BR_BUS_WD-1:0] es_branch_bus;
wire [`ysyx_040991_DATA_WIDTH-1:0] es_alu_src1;
wire [`ysyx_040991_DATA_WIDTH-1:0] es_alu_src2;
wire [ 3:0] es_mul_op;
wire [ 3:0] es_div_op;
wire es_word_op;
wire div;
// wire div_complete;
wire [11:0] es_csr_raddr;
wire [63:0] es_csr_rdata;
wire [`ysyx_040991_CSR_FORWARDING_BUS_WD -1:0] ms_csr_forwarding_bus;
wire [`ysyx_040991_CSR_FORWARDING_BUS_WD -1:0] ws_csr_forwarding_bus;
ysyx_040991_exe_stage u_es (
.clk (clk ),
.rst (rst ),
// allowin
.ms_allowin (ms_allowin ),
.es_allowin (es_allowin ),
// from ds
.ds_to_es_valid (ds_to_es_valid ),
.ds_to_es_bus (ds_to_es_bus ),
.ds_to_es_exception (ds_to_es_exception ),
// to ms
.es_to_ms_valid (es_to_ms_valid ),
.es_to_ms_bus (es_to_ms_bus ),
.es_to_ms_exception (es_to_ms_exception ),
// to from ctrl
.ds_to_es_hold (ds_to_es_hold ),
.es_branch_bus (es_branch_bus ),
.ws_flush (ws_flush ),
.ms_is_exception (ms_is_exception ),
// dcache ports
.dcache_valid (dcache_valid ),
.dcache_uncache (dcache_uncache ),
.dcache_op (dcache_op ),
.dcache_index (dcache_index ),
.dcache_tag (dcache_tag ),
.dcache_offset (dcache_offset ),
.dcache_wstrb (dcache_wstrb ),
.dcache_wdata (dcache_wdata ),
.dcache_addr_ok (dcache_addr_ok ),
.es_fence (es_fence ),
.es_fence_complete (es_fence_complete ),
// forwarding bus
.es_forwarding_bus (es_forwarding_bus ),
// multiplier divider
.es_alu_src1 (es_alu_src1 ),
.es_alu_src2 (es_alu_src2 ),
.es_mul_op (es_mul_op ),
.es_div_op (es_div_op ),
.es_word_op (es_word_op ),
.div (div ),
// csr
.es_csr_raddr (es_csr_raddr ),
.es_csr_rdata (es_csr_rdata ),
// forwarding csr register
.ms_csr_forwarding_bus (ms_csr_forwarding_bus ),
.ws_csr_forwarding_bus (ws_csr_forwarding_bus )
);
// mem_stage
wire ws_allowin;
wire ms_to_ws_valid;
wire [`ysyx_040991_MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus;
wire [`ysyx_040991_DATA_WIDTH-1:0] ms_mul_result;
wire [`ysyx_040991_DATA_WIDTH-1:0] ms_div_result;
wire [`ysyx_040991_EXCEPTION_WD -1:0] ms_to_ws_exception;
ysyx_040991_mem_stage u_ms (
.clk (clk ),
.rst (rst ),
// allowin
.ws_allowin (ws_allowin ),
.ms_allowin (ms_allowin ),
// from es
.es_to_ms_valid (es_to_ms_valid ),
.es_to_ms_bus (es_to_ms_bus ),
.es_to_ms_exception (es_to_ms_exception ),
// to ws
.ms_to_ws_valid (ms_to_ws_valid ),
.ms_to_ws_bus (ms_to_ws_bus ),
.ms_to_ws_exception (ms_to_ws_exception ),
// from ctrl
.ws_flush (ws_flush ),
.ms_is_exception (ms_is_exception ),
// dcache ports
.dcache_data_ok (dcache_data_ok ),
.dcache_rdata (dcache_rdata ),
// forwarding bus
.ms_forwarding_bus (ms_forwarding_bus ),
.ms_csr_forwarding_bus (ms_csr_forwarding_bus ),
// multiplier divider results
.ms_mul_result (ms_mul_result ),
.ms_div_result (ms_div_result )
);
wire csr_wen;
wire [11:0] csr_waddr;
wire [63:0] csr_wdata;
wire [5:0] ws_exception;
wire ws_exception_valid;
wire [63:0] ws_exception_pc;
// wb_stage
ysyx_040991_wb_stage u_ws(
.clk(clk),
.rst(rst),
// allowin
.ws_allowin(ws_allowin),
// from ms
.ms_to_ws_valid(ms_to_ws_valid),
.ms_to_ws_bus(ms_to_ws_bus),
.ms_to_ws_exception(ms_to_ws_exception),
// to rf: for write back
.ws_to_rf_bus(ws_to_rf_bus),
// forwarding bus
.ws_forwarding_bus(ws_forwarding_bus),
.ws_csr_forwarding_bus(ws_csr_forwarding_bus),
// to csr
.csr_wen (csr_wen ),
.csr_waddr (csr_waddr ),
.csr_wdata (csr_wdata ),
.ws_exception (ws_exception ),
.ws_is_exception (ws_is_exception ),
.ws_is_eret (ws_is_eret ),
.ws_exception_valid (ws_exception_valid ),
.ws_exception_pc (ws_exception_pc )
);
// stall
// stall fs_to_ds_bus and ds_to_es_bus
ysyx_040991_ctrl u_ctrl(
// from ds
.ds_branch_bus(ds_branch_bus),
// from es
.es_branch_bus(es_branch_bus),
// to es
.ds_to_es_hold(ds_to_es_hold),
// to fs
.br_bus(br_bus)
);
// exe stage -> mul, div -> mem_stage
ysyx_040991_multiplier #(
.ysyx_040991_DATA_WIDTH(`ysyx_040991_DATA_WIDTH)
) u_multiplier (
.clk(clk),
.rst(rst),
.mul_src1(es_alu_src1),
.mul_src2(es_alu_src2),
.mul_op(es_mul_op),
.word_op(es_word_op),
.mul_wb_result(ms_mul_result)
);
ysyx_040991_divider #(
.ysyx_040991_DATA_WIDTH(`ysyx_040991_DATA_WIDTH)
) u_divider (
.clk(clk),
.rst(rst),
.div_src1(es_alu_src1),
.div_src2(es_alu_src2),
.div_op(es_div_op),
.word_op(es_word_op),
.div(div),
// .complete(div_complete),
.div_wb_result(ms_div_result)
);
ysyx_040991_csr u_csr(
.clk (clk ),
.rst (rst ),
.timer_intr (interrupt_taken ),
.csr_raddr (es_csr_raddr ),
.csr_rdata (es_csr_rdata ),
.csr_wen (csr_wen ),
.csr_waddr (csr_waddr ),
.csr_wdata (csr_wdata ),
.ws_exception (ws_exception ),
.ws_exception_valid(ws_exception_valid),
.ws_exception_pc (ws_exception_pc ),
.csr_branch_pc (csr_branch_pc ),
.timer_interrupt_en(timer_interrupt_en)
);
endmodule
module ysyx_040991_npc_top #(
parameter C_M_AXI_ID_WIDTH = 4,
parameter C_M_AXI_ADDR_WIDTH = 32,
parameter C_M_AXI_ysyx_040991_DATA_WIDTH = 64,
parameter C_M_AXI_AWUSER_WIDTH = 1,
parameter C_M_AXI_ARUSER_WIDTH = 1,
parameter C_M_AXI_WUSER_WIDTH = 1,
parameter C_M_AXI_RUSER_WIDTH = 1,
parameter C_M_AXI_BUSER_WIDTH = 1,
parameter C_S_AXI_ID_WIDTH = 4,
parameter C_S_AXI_ysyx_040991_DATA_WIDTH = 64,
parameter C_S_AXI_ADDR_WIDTH = 32,
parameter C_S_AXI_AWUSER_WIDTH = 1,
parameter C_S_AXI_ARUSER_WIDTH = 1,
parameter C_S_AXI_WUSER_WIDTH = 1,
parameter C_S_AXI_RUSER_WIDTH = 1,
parameter C_S_AXI_BUSER_WIDTH = 1
)(
input clk,
input rst,
input interrupt_taken,
// M_AXI4
output wire [C_M_AXI_ID_WIDTH-1 : 0] mem_axi_awid,
output wire [C_M_AXI_ADDR_WIDTH-1 : 0] mem_axi_awaddr,
output wire [7 : 0] mem_axi_awlen,
output wire [2 : 0] mem_axi_awsize,
output wire [1 : 0] mem_axi_awburst,
output wire mem_axi_awlock,
output wire [3 : 0] mem_axi_awcache,
output wire [2 : 0] mem_axi_awprot,
output wire [3 : 0] mem_axi_awqos,
output wire [3 : 0] mem_axi_awregion,
output wire [C_M_AXI_AWUSER_WIDTH-1 : 0] mem_axi_awuser,
output wire mem_axi_awvalid,
input wire mem_axi_awready,
output wire [C_M_AXI_ysyx_040991_DATA_WIDTH-1 : 0] mem_axi_wdata,
output wire [C_M_AXI_ysyx_040991_DATA_WIDTH/8-1 : 0] mem_axi_wstrb,
output wire mem_axi_wlast,
output wire [C_M_AXI_WUSER_WIDTH-1 : 0] mem_axi_wuser,
output wire mem_axi_wvalid,
input wire mem_axi_wready,
input wire [C_M_AXI_ID_WIDTH-1 : 0] mem_axi_bid,
input wire [1 : 0] mem_axi_bresp,
input wire [C_M_AXI_BUSER_WIDTH-1 : 0] mem_axi_buser,
input wire mem_axi_bvalid,
output wire mem_axi_bready,
output wire [C_M_AXI_ID_WIDTH-1 : 0] mem_axi_arid,
output wire [C_M_AXI_ADDR_WIDTH-1 : 0] mem_axi_araddr,
output wire [7 : 0] mem_axi_arlen,
output wire [2 : 0] mem_axi_arsize,
output wire [1 : 0] mem_axi_arburst,
output wire mem_axi_arlock,
output wire [3 : 0] mem_axi_arcache,
output wire [2 : 0] mem_axi_arprot,
output wire [3 : 0] mem_axi_arqos,
output wire [3 : 0] mem_axi_arregion,
output wire [C_M_AXI_ARUSER_WIDTH-1 : 0] mem_axi_aruser,
output wire mem_axi_arvalid,
input wire mem_axi_arready,
input wire [C_M_AXI_ID_WIDTH-1 : 0] mem_axi_rid,
input wire [C_M_AXI_ysyx_040991_DATA_WIDTH-1 : 0] mem_axi_rdata,
input wire [1 : 0] mem_axi_rresp,
input wire mem_axi_rlast,
input wire [C_M_AXI_RUSER_WIDTH-1 : 0] mem_axi_ruser,
input wire mem_axi_rvalid,
output wire mem_axi_rready,
// S_AXI4
input wire [C_S_AXI_ID_WIDTH-1 : 0] io_slave_awid,
input wire [C_S_AXI_ADDR_WIDTH-1 : 0] io_slave_awaddr,
input wire [7 : 0] io_slave_awlen,
input wire [2 : 0] io_slave_awsize,
input wire [1 : 0] io_slave_awburst,
input wire io_slave_awlock,
input wire [3 : 0] io_slave_awcache,
input wire [2 : 0] io_slave_awprot,
input wire [3 : 0] io_slave_awqos,
input wire [3 : 0] io_slave_awregion,
input wire [C_S_AXI_AWUSER_WIDTH-1 : 0] io_slave_awuser,
input wire io_slave_awvalid,
output wire io_slave_awready,
input wire [C_S_AXI_ysyx_040991_DATA_WIDTH-1 : 0] io_slave_wdata,
input wire [(C_S_AXI_ysyx_040991_DATA_WIDTH/8)-1 : 0] io_slave_wstrb,
input wire io_slave_wlast,
input wire [C_S_AXI_WUSER_WIDTH-1 : 0] io_slave_wuser,
input wire io_slave_wvalid,
output wire io_slave_wready,
output wire [C_S_AXI_ID_WIDTH-1 : 0] io_slave_bid,
output wire [1 : 0] io_slave_bresp,
output wire [C_S_AXI_BUSER_WIDTH-1 : 0] io_slave_buser,
output wire io_slave_bvalid,
input wire io_slave_bready,
input wire [C_S_AXI_ID_WIDTH-1 : 0] io_slave_arid,
input wire [C_S_AXI_ADDR_WIDTH-1 : 0] io_slave_araddr,
input wire [7 : 0] io_slave_arlen,
input wire [2 : 0] io_slave_arsize,
input wire [1 : 0] io_slave_arburst,
input wire io_slave_arlock,
input wire [3 : 0] io_slave_arcache,
input wire [2 : 0] io_slave_arprot,
input wire [3 : 0] io_slave_arqos,
input wire [3 : 0] io_slave_arregion,
input wire [C_S_AXI_ARUSER_WIDTH-1 : 0] io_slave_aruser,
input wire io_slave_arvalid,
output wire io_slave_arready,
output wire [C_S_AXI_ID_WIDTH-1 : 0] io_slave_rid,
output wire [C_S_AXI_ysyx_040991_DATA_WIDTH-1 : 0] io_slave_rdata,
output wire [1 : 0] io_slave_rresp,
output wire io_slave_rlast,
output wire [C_S_AXI_RUSER_WIDTH-1 : 0] io_slave_ruser,
output wire io_slave_rvalid,
input wire io_slave_rready,
// icache
// data_bank0 of ram0
input [128 -1:0] icache_ram0_bank0_Q,
output icache_ram0_bank0_CEN,
output icache_ram0_bank0_WEN,
output [128 -1:0] icache_ram0_bank0_BWEN,
output [6 -1:0] icache_ram0_bank0_A,
output [128 -1:0] icache_ram0_bank0_D,
// data_bank1 of ram0
input [128 -1:0] icache_ram0_bank1_Q,
output icache_ram0_bank1_CEN,
output icache_ram0_bank1_WEN,
output [128 -1:0] icache_ram0_bank1_BWEN,
output [6 -1:0] icache_ram0_bank1_A,
output [128 -1:0] icache_ram0_bank1_D,
// data_bank0 of ram1
input [128 -1:0] icache_ram1_bank0_Q,
output icache_ram1_bank0_CEN,
output icache_ram1_bank0_WEN,
output [128 -1:0] icache_ram1_bank0_BWEN,
output [6 -1:0] icache_ram1_bank0_A,
output [128 -1:0] icache_ram1_bank0_D,
// data_bank1 of ram1
input [128 -1:0] icache_ram1_bank1_Q,
output icache_ram1_bank1_CEN,
output icache_ram1_bank1_WEN,
output [128 -1:0] icache_ram1_bank1_BWEN,
output [6 -1:0] icache_ram1_bank1_A,
output [128 -1:0] icache_ram1_bank1_D,
// dcache
// data_bank0 of ram0
input [128 -1:0] dcache_ram0_bank0_Q,
output dcache_ram0_bank0_CEN,
output dcache_ram0_bank0_WEN,
output [128 -1:0] dcache_ram0_bank0_BWEN,
output [6 -1:0] dcache_ram0_bank0_A,
output [128 -1:0] dcache_ram0_bank0_D,
// data_bank1 of ram0
input [128 -1:0] dcache_ram0_bank1_Q,
output dcache_ram0_bank1_CEN,
output dcache_ram0_bank1_WEN,
output [128 -1:0] dcache_ram0_bank1_BWEN,
output [6 -1:0] dcache_ram0_bank1_A,
output [128 -1:0] dcache_ram0_bank1_D,
// data_bank0 of ram1
input [128 -1:0] dcache_ram1_bank0_Q,
output dcache_ram1_bank0_CEN,
output dcache_ram1_bank0_WEN,
output [128 -1:0] dcache_ram1_bank0_BWEN,
output [6 -1:0] dcache_ram1_bank0_A,
output [128 -1:0] dcache_ram1_bank0_D,
// data_bank1 of ram1
input [128 -1:0] dcache_ram1_bank1_Q,
output dcache_ram1_bank1_CEN,
output dcache_ram1_bank1_WEN,
output [128 -1:0] dcache_ram1_bank1_BWEN,
output [6 -1:0] dcache_ram1_bank1_A,
output [128 -1:0] dcache_ram1_bank1_D
);
wire icache_valid ;
wire icache_uncache ;
wire icache_op ; // 0: read only
wire [`ysyx_040991_CACHE_INDEX_WD -1:0] icache_index ;
wire [`ysyx_040991_CACHE_TAG_WD -1:0] icache_tag ;
wire [`ysyx_040991_CACHE_OFFSET_WD -1:0] icache_offset ;
wire icache_addr_ok ;
wire icache_data_ok ;
wire [63:0] icache_rdata ;
wire dcache_valid ;
wire dcache_uncache ;
wire dcache_op ; // 0: read, 1: write
wire [`ysyx_040991_CACHE_INDEX_WD -1:0] dcache_index ;
wire [`ysyx_040991_CACHE_TAG_WD -1:0] dcache_tag ;
wire [`ysyx_040991_CACHE_OFFSET_WD -1:0] dcache_offset ;
wire [ 7:0] dcache_wstrb ;
wire [63:0] dcache_wdata ;
wire dcache_addr_ok ;
wire dcache_data_ok ;
wire [63:0] dcache_rdata ;
wire es_fence;
wire es_fence_complete;
ysyx_040991_npc_core u_npc_core(
.clk (clk ),
.rst (rst ),
.interrupt_taken (interrupt_taken ),
// to cache
.icache_valid (icache_valid ),
.icache_uncache (icache_uncache ),
.icache_op (icache_op ),
.icache_index (icache_index ),
.icache_tag (icache_tag ),
.icache_offset (icache_offset ),
.icache_addr_ok (icache_addr_ok ),
.icache_data_ok (icache_data_ok ),
.icache_rdata (icache_rdata ),
.dcache_valid (dcache_valid ),
.dcache_uncache (dcache_uncache ),
.dcache_op (dcache_op ),
.dcache_index (dcache_index ),
.dcache_tag (dcache_tag ),
.dcache_offset (dcache_offset ),
.dcache_wstrb (dcache_wstrb ),
.dcache_wdata (dcache_wdata ),
.dcache_addr_ok (dcache_addr_ok ),
.dcache_data_ok (dcache_data_ok ),
.dcache_rdata (dcache_rdata ),
.es_fence (es_fence ),
.es_fence_complete (es_fence_complete)
);
ysyx_040991_cache_top
#(
.C_M_AXI_ID_WIDTH (C_M_AXI_ID_WIDTH ),
.C_M_AXI_ADDR_WIDTH (C_M_AXI_ADDR_WIDTH ),
.C_M_AXI_ysyx_040991_DATA_WIDTH (C_M_AXI_ysyx_040991_DATA_WIDTH ),
.C_M_AXI_AWUSER_WIDTH (C_M_AXI_AWUSER_WIDTH ),
.C_M_AXI_ARUSER_WIDTH (C_M_AXI_ARUSER_WIDTH ),
.C_M_AXI_WUSER_WIDTH (C_M_AXI_WUSER_WIDTH ),
.C_M_AXI_RUSER_WIDTH (C_M_AXI_RUSER_WIDTH ),
.C_M_AXI_BUSER_WIDTH (C_M_AXI_BUSER_WIDTH )
)
u_cache_top(
.clk (clk ),
.rst (rst ),
// from npc
.icache_valid (icache_valid ),
.icache_uncache (icache_uncache ),
.icache_op (icache_op ),
.icache_index (icache_index ),
.icache_tag (icache_tag ),
.icache_offset (icache_offset ),
.icache_addr_ok (icache_addr_ok ),
.icache_data_ok (icache_data_ok ),
.icache_rdata (icache_rdata ),
.dcache_valid (dcache_valid ),
.dcache_uncache (dcache_uncache ),
.dcache_op (dcache_op ),
.dcache_index (dcache_index ),
.dcache_tag (dcache_tag ),
.dcache_offset (dcache_offset ),
.dcache_wstrb (dcache_wstrb ),
.dcache_wdata (dcache_wdata ),
.dcache_addr_ok (dcache_addr_ok ),
.dcache_data_ok (dcache_data_ok ),
.dcache_rdata (dcache_rdata ),
.es_fence (es_fence ),
.es_fence_complete (es_fence_complete),
// AXI4
.M_AXI_AWID (mem_axi_awid ),
.M_AXI_AWADDR (mem_axi_awaddr ),
.M_AXI_AWLEN (mem_axi_awlen ),
.M_AXI_AWSIZE (mem_axi_awsize ),
.M_AXI_AWBURST (mem_axi_awburst ),
.M_AXI_AWLOCK (mem_axi_awlock ),
.M_AXI_AWCACHE (mem_axi_awcache ),
.M_AXI_AWPROT (mem_axi_awprot ),
.M_AXI_AWQOS (mem_axi_awqos ),
.M_AXI_AWREGION (mem_axi_awregion ),
.M_AXI_AWUSER (mem_axi_awuser ),
.M_AXI_AWVALID (mem_axi_awvalid ),
.M_AXI_AWREADY (mem_axi_awready ),
.M_AXI_WDATA (mem_axi_wdata ),
.M_AXI_WSTRB (mem_axi_wstrb ),
.M_AXI_WLAST (mem_axi_wlast ),
.M_AXI_WUSER (mem_axi_wuser ),
.M_AXI_WVALID (mem_axi_wvalid ),
.M_AXI_WREADY (mem_axi_wready ),
.M_AXI_BID (mem_axi_bid ),
.M_AXI_BRESP (mem_axi_bresp ),
.M_AXI_BUSER (mem_axi_buser ),
.M_AXI_BVALID (mem_axi_bvalid ),
.M_AXI_BREADY (mem_axi_bready ),
.M_AXI_ARID (mem_axi_arid ),
.M_AXI_ARADDR (mem_axi_araddr ),
.M_AXI_ARLEN (mem_axi_arlen ),
.M_AXI_ARSIZE (mem_axi_arsize ),
.M_AXI_ARBURST (mem_axi_arburst ),
.M_AXI_ARLOCK (mem_axi_arlock ),
.M_AXI_ARCACHE (mem_axi_arcache ),
.M_AXI_ARPROT (mem_axi_arprot ),
.M_AXI_ARQOS (mem_axi_arqos ),
.M_AXI_ARREGION (mem_axi_arregion ),
.M_AXI_ARUSER (mem_axi_aruser ),
.M_AXI_ARVALID (mem_axi_arvalid ),
.M_AXI_ARREADY (mem_axi_arready ),
.M_AXI_RID (mem_axi_rid ),
.M_AXI_RDATA (mem_axi_rdata ),
.M_AXI_RRESP (mem_axi_rresp ),
.M_AXI_RLAST (mem_axi_rlast ),
.M_AXI_RUSER (mem_axi_ruser ),
.M_AXI_RVALID (mem_axi_rvalid ),
.M_AXI_RREADY (mem_axi_rready ),
.icache_ram0_bank0_Q (icache_ram0_bank0_Q ),
.icache_ram0_bank0_CEN (icache_ram0_bank0_CEN ),
.icache_ram0_bank0_WEN (icache_ram0_bank0_WEN ),
.icache_ram0_bank0_BWEN (icache_ram0_bank0_BWEN ),
.icache_ram0_bank0_A (icache_ram0_bank0_A ),
.icache_ram0_bank0_D (icache_ram0_bank0_D ),
.icache_ram0_bank1_Q (icache_ram0_bank1_Q ),
.icache_ram0_bank1_CEN (icache_ram0_bank1_CEN ),
.icache_ram0_bank1_WEN (icache_ram0_bank1_WEN ),
.icache_ram0_bank1_BWEN (icache_ram0_bank1_BWEN ),
.icache_ram0_bank1_A (icache_ram0_bank1_A ),
.icache_ram0_bank1_D (icache_ram0_bank1_D ),
.icache_ram1_bank0_Q (icache_ram1_bank0_Q ),
.icache_ram1_bank0_CEN (icache_ram1_bank0_CEN ),
.icache_ram1_bank0_WEN (icache_ram1_bank0_WEN ),
.icache_ram1_bank0_BWEN (icache_ram1_bank0_BWEN ),
.icache_ram1_bank0_A (icache_ram1_bank0_A ),
.icache_ram1_bank0_D (icache_ram1_bank0_D ),
.icache_ram1_bank1_Q (icache_ram1_bank1_Q ),
.icache_ram1_bank1_CEN (icache_ram1_bank1_CEN ),
.icache_ram1_bank1_WEN (icache_ram1_bank1_WEN ),
.icache_ram1_bank1_BWEN (icache_ram1_bank1_BWEN ),
.icache_ram1_bank1_A (icache_ram1_bank1_A ),
.icache_ram1_bank1_D (icache_ram1_bank1_D ),
.dcache_ram0_bank0_Q (dcache_ram0_bank0_Q ),
.dcache_ram0_bank0_CEN (dcache_ram0_bank0_CEN ),
.dcache_ram0_bank0_WEN (dcache_ram0_bank0_WEN ),
.dcache_ram0_bank0_BWEN (dcache_ram0_bank0_BWEN ),
.dcache_ram0_bank0_A (dcache_ram0_bank0_A ),
.dcache_ram0_bank0_D (dcache_ram0_bank0_D ),
.dcache_ram0_bank1_Q (dcache_ram0_bank1_Q ),
.dcache_ram0_bank1_CEN (dcache_ram0_bank1_CEN ),
.dcache_ram0_bank1_WEN (dcache_ram0_bank1_WEN ),
.dcache_ram0_bank1_BWEN (dcache_ram0_bank1_BWEN ),
.dcache_ram0_bank1_A (dcache_ram0_bank1_A ),
.dcache_ram0_bank1_D (dcache_ram0_bank1_D ),
.dcache_ram1_bank0_Q (dcache_ram1_bank0_Q ),
.dcache_ram1_bank0_CEN (dcache_ram1_bank0_CEN ),
.dcache_ram1_bank0_WEN (dcache_ram1_bank0_WEN ),
.dcache_ram1_bank0_BWEN (dcache_ram1_bank0_BWEN ),
.dcache_ram1_bank0_A (dcache_ram1_bank0_A ),
.dcache_ram1_bank0_D (dcache_ram1_bank0_D ),
.dcache_ram1_bank1_Q (dcache_ram1_bank1_Q ),
.dcache_ram1_bank1_CEN (dcache_ram1_bank1_CEN ),
.dcache_ram1_bank1_WEN (dcache_ram1_bank1_WEN ),
.dcache_ram1_bank1_BWEN (dcache_ram1_bank1_BWEN ),
.dcache_ram1_bank1_A (dcache_ram1_bank1_A ),
.dcache_ram1_bank1_D (dcache_ram1_bank1_D )
);
assign io_slave_awready = 'b0;
assign io_slave_wready = 'b0;
assign io_slave_bid = 'b0;
assign io_slave_bresp = 'b0;
assign io_slave_buser = 'b0;
assign io_slave_bvalid = 'b0;
assign io_slave_arready = 'b0;
assign io_slave_rid = 'b0;
assign io_slave_rdata = 'b0;
assign io_slave_rresp = 'b0;
assign io_slave_rlast = 'b0;
assign io_slave_ruser = 'b0;
assign io_slave_rvalid = 'b0;
endmodule
module ysyx_040991_RegisterFile # (
parameter ysyx_040991_DATA_WIDTH = 64
)(
input clk,
// READ PORT 1
input [4:0] raddr1,
output[ysyx_040991_DATA_WIDTH-1:0] rdata1,
// READ PORT 2
input [4:0] raddr2,
output[ysyx_040991_DATA_WIDTH-1:0] rdata2,
// WRITE PORT1
input [ysyx_040991_DATA_WIDTH-1:0] wb_data,
input [4:0] wb_addr,
input wen
);
reg [ysyx_040991_DATA_WIDTH-1:0] rf [0:31];
integer i;
initial begin
for(i=0; i<31; i=i+1) begin
rf[i] = 64'b0;
end
end
always @ (posedge clk) begin
if (wen) begin
rf[wb_addr] <= (wb_addr == 5'b0) ? 64'b0 : wb_data;
end
end
assign rdata1 = (raddr1 == 5'b0) ? 64'b0 : rf[raddr1];
assign rdata2 = (raddr2 == 5'b0) ? 64'b0 : rf[raddr2];
endmodule
module ysyx_040991_tag_v_ram (
input clk ,
input rst ,
input cen ,
input [`ysyx_040991_CACHE_INDEX_WD -1:0] addr,
input [`ysyx_040991_CACHE_TAG_WD :0] din ,
input wen ,
output reg [`ysyx_040991_CACHE_TAG_WD :0] dout
);
integer i;
reg [`ysyx_040991_CACHE_TAG_WD:0] ram [0:2**`ysyx_040991_CACHE_INDEX_WD-1];
always @(posedge clk) begin
if (rst) begin
for (i = 0; i < 2**`ysyx_040991_CACHE_INDEX_WD; i=i+1) begin
ram[i] <= 'b0;
end
end
else if (wen && cen) begin
ram[addr] <= din;
end
dout <= cen ? ram[addr] : 'hffff;
end
endmodule
module ysyx_040991_wallace_tree (
input [16:0] din,
input [13:0] cin,
output [13:0] cout,
output c_final,
output s_final
);
wire [4:0] s0;
wire [3:0] s1;
wire [1:0] s2;
wire [1:0] s3;
wire s4;
ysyx_040991_adder3 u_adder00 (.a(din[4]), .b(din[3]), .cin(din[2]), .cout(cout[0]), .s(s0[0]));
ysyx_040991_adder3 u_adder01 (.a(din[7]), .b(din[6]), .cin(din[5]), .cout(cout[1]), .s(s0[1]));
ysyx_040991_adder3 u_adder02 (.a(din[10]), .b(din[9]), .cin(din[8]), .cout(cout[2]), .s(s0[2]));
ysyx_040991_adder3 u_adder03 (.a(din[13]), .b(din[12]), .cin(din[11]), .cout(cout[3]), .s(s0[3]));
ysyx_040991_adder3 u_adder04 (.a(din[16]), .b(din[15]), .cin(din[14]), .cout(cout[4]), .s(s0[4]));
ysyx_040991_adder3 u_adder10 (.a(cin[2]), .b(cin[1]), .cin(cin[0]), .cout(cout[5]), .s(s1[0]));
ysyx_040991_adder3 u_adder11 (.a(din[0]), .b(cin[4]), .cin(cin[3]), .cout(cout[6]), .s(s1[1]));
ysyx_040991_adder3 u_adder12 (.a(s0[1]), .b(s0[0]), .cin(din[1]), .cout(cout[7]), .s(s1[2]));
ysyx_040991_adder3 u_adder13 (.a(s0[4]), .b(s0[3]), .cin(s0[2]), .cout(cout[8]), .s(s1[3]));
ysyx_040991_adder3 u_adder20 (.a(s1[0]), .b(cin[6]), .cin(cin[5]), .cout(cout[9]), .s(s2[0]));
ysyx_040991_adder3 u_adder21 (.a(s1[3]), .b(s1[2]), .cin(s1[1]), .cout(cout[10]), .s(s2[1]));
ysyx_040991_adder3 u_adder30 (.a(cin[9]), .b(cin[8]), .cin(cin[7]), .cout(cout[11]), .s(s3[0]));
ysyx_040991_adder3 u_adder31 (.a(s2[1]), .b(s2[0]), .cin(cin[10]), .cout(cout[12]), .s(s3[1]));
ysyx_040991_adder3 u_adder40 (.a(s3[1]), .b(s3[0]), .cin(cin[11]), .cout(cout[13]), .s(s4));
ysyx_040991_adder3 u_adder50 (.a(s4), .b(cin[13]), .cin(cin[12]), .cout(c_final), .s(s_final));
endmodule
module ysyx_040991_wb_stage(
input clk ,
input rst ,
//allowin
output ws_allowin ,
//from ms
input ms_to_ws_valid,
input [`ysyx_040991_MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus ,
input [`ysyx_040991_EXCEPTION_WD -1:0] ms_to_ws_exception,
//to rf: for write back
output [`ysyx_040991_WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus ,
// forwarding bus
output [`ysyx_040991_WS_FORWARDING_BUS_WD -1:0] ws_forwarding_bus,
// to es csr forwarding bus
output [`ysyx_040991_CSR_FORWARDING_BUS_WD -1:0] ws_csr_forwarding_bus,
// to csr
output csr_wen,
output [11:0] csr_waddr,
output [63:0] csr_wdata,
output [5:0] ws_exception,
output ws_is_exception,
output ws_is_eret,
output ws_exception_valid,
output [63:0] ws_exception_pc
);
reg ws_valid;
wire ws_ready_go;
reg [`ysyx_040991_MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus_r;
reg [`ysyx_040991_EXCEPTION_WD -1:0] ms_to_ws_exception_r;
wire ws_rd_wen ;
wire [4:0] ws_rd_addr ;
wire [`ysyx_040991_DATA_WIDTH-1:0] ws_final_result ;
wire [63:0] ws_pc ;
wire [31:0] ws_inst;
wire [`ysyx_040991_DATA_WIDTH-1:0] ws_alu_result;
wire ws_csr_wen;
// wire ws_dcache_uncache;
assign {
// ws_dcache_uncache ,
ws_rd_wen ,
ws_rd_addr ,
ws_final_result ,
ws_alu_result ,
ws_csr_wen ,
ws_pc ,
ws_inst
} = ms_to_ws_bus_r;
wire rf_wen;
wire [4 :0] rf_waddr;
wire [`ysyx_040991_DATA_WIDTH-1:0] rf_wdata;
assign ws_to_rf_bus = {
rf_wen ,
rf_waddr ,
rf_wdata
};
assign ws_is_exception = ws_valid && ((ws_exception[5:4] == `ysyx_040991_EXCEPTION_EXCEPTION) || (ws_exception[5:4] == `ysyx_040991_EXCEPTION_INTERRUPT));
assign ws_is_eret = ws_valid && (ws_exception[5:4] == `ysyx_040991_EXCEPTION_ERET);
assign ws_exception_valid = ws_valid;
wire ws_flush;
assign ws_flush = ws_is_eret || ws_is_exception;
reg ws_flush_r;
always @(posedge clk) begin
if (rst) begin
ws_flush_r <= 1'b0;
end else if (ws_is_eret || ws_is_exception) begin
ws_flush_r <= 1'b1;
end else if (ms_to_ws_valid && ws_allowin) begin
ws_flush_r <= 1'b0;
end
end
assign ws_ready_go = 1'b1;
assign ws_allowin = !ws_valid || ws_ready_go;
always @(posedge clk) begin
if (rst) begin
ws_valid <= 1'b0;
end
else if (ws_allowin) begin
ws_valid <= ms_to_ws_valid;
end
if (ms_to_ws_valid && ws_allowin) begin
ms_to_ws_bus_r <= ms_to_ws_bus;
ms_to_ws_exception_r <= ms_to_ws_exception;
end
end
assign rf_wen = ws_rd_wen && ws_valid && !(ws_flush || ws_flush_r);
assign rf_waddr = ws_rd_addr;
assign rf_wdata = ws_final_result;
assign csr_wen = ws_csr_wen && ws_valid;
assign csr_waddr = ws_inst[31:20];
assign csr_wdata = ws_alu_result;
assign ws_forwarding_bus = {
rf_wen,
rf_waddr,
rf_wdata
};
assign ws_csr_forwarding_bus = {
csr_wen,
csr_waddr,
csr_wdata
};
assign ws_exception = ms_to_ws_exception_r;
assign ws_exception_pc = ws_pc;
endmodule
module ysyx_040991 (
input clock,
input reset,
input io_interrupt,
input io_master_awready,
output io_master_awvalid,
output [3:0] io_master_awid,
output [31:0] io_master_awaddr,
output [7:0] io_master_awlen,
output [2:0] io_master_awsize,
output [1:0] io_master_awburst,
input io_master_wready,
output io_master_wvalid,
output [63:0] io_master_wdata,
output [7:0] io_master_wstrb,
output io_master_wlast,
output io_master_bready,
input io_master_bvalid,
input [3:0] io_master_bid,
input [1:0] io_master_bresp,
input io_master_arready,
output io_master_arvalid,
output [3:0] io_master_arid,
output [31:0] io_master_araddr,
output [7:0] io_master_arlen,
output [2:0] io_master_arsize,
output [1:0] io_master_arburst,
output io_master_rready,
input io_master_rvalid,
input [3:0] io_master_rid,
input [1:0] io_master_rresp,
input [63:0] io_master_rdata,
input io_master_rlast,
output io_slave_awready,
input io_slave_awvalid,
input [3:0] io_slave_awid,
input [31:0] io_slave_awaddr,
input [7:0] io_slave_awlen,
input [2:0] io_slave_awsize,
input [1:0] io_slave_awburst,
output io_slave_wready,
input io_slave_wvalid,
input [63:0] io_slave_wdata,
input [7:0] io_slave_wstrb,
input io_slave_wlast,
input io_slave_bready,
output io_slave_bvalid,
output [3:0] io_slave_bid,
output [1:0] io_slave_bresp,
output io_slave_arready,
input io_slave_arvalid,
input [3:0] io_slave_arid,
input [31:0] io_slave_araddr,
input [7:0] io_slave_arlen,
input [2:0] io_slave_arsize,
input [1:0] io_slave_arburst,
input io_slave_rready,
output io_slave_rvalid,
output [3:0] io_slave_rid,
output [1:0] io_slave_rresp,
output [63:0] io_slave_rdata,
output io_slave_rlast,
output [5:0] io_sram0_addr,
output io_sram0_cen,
output io_sram0_wen,
output [127:0] io_sram0_wmask,
output [127:0] io_sram0_wdata,
input [127:0] io_sram0_rdata,
output [5:0] io_sram1_addr,
output io_sram1_cen,
output io_sram1_wen,
output [127:0] io_sram1_wmask,
output [127:0] io_sram1_wdata,
input [127:0] io_sram1_rdata,
output [5:0] io_sram2_addr,
output io_sram2_cen,
output io_sram2_wen,
output [127:0] io_sram2_wmask,
output [127:0] io_sram2_wdata,
input [127:0] io_sram2_rdata,
output [5:0] io_sram3_addr,
output io_sram3_cen,
output io_sram3_wen,
output [127:0] io_sram3_wmask,
output [127:0] io_sram3_wdata,
input [127:0] io_sram3_rdata,
output [5:0] io_sram4_addr,
output io_sram4_cen,
output io_sram4_wen,
output [127:0] io_sram4_wmask,
output [127:0] io_sram4_wdata,
input [127:0] io_sram4_rdata,
output [5:0] io_sram5_addr,
output io_sram5_cen,
output io_sram5_wen,
output [127:0] io_sram5_wmask,
output [127:0] io_sram5_wdata,
input [127:0] io_sram5_rdata,
output [5:0] io_sram6_addr,
output io_sram6_cen,
output io_sram6_wen,
output [127:0] io_sram6_wmask,
output [127:0] io_sram6_wdata,
input [127:0] io_sram6_rdata,
output [5:0] io_sram7_addr,
output io_sram7_cen,
output io_sram7_wen,
output [127:0] io_sram7_wmask,
output [127:0] io_sram7_wdata,
input [127:0] io_sram7_rdata
);
parameter C_M_AXI_ID_WIDTH = 4;
parameter C_M_AXI_ADDR_WIDTH = 32;
parameter C_M_AXI_ysyx_040991_DATA_WIDTH = 64;
parameter C_M_AXI_AWUSER_WIDTH = 1;
parameter C_M_AXI_ARUSER_WIDTH = 1;
parameter C_M_AXI_WUSER_WIDTH = 1;
parameter C_M_AXI_RUSER_WIDTH = 1;
parameter C_M_AXI_BUSER_WIDTH = 1;
wire [C_M_AXI_ID_WIDTH-1 : 0] mem_axi_awid;
wire [C_M_AXI_ADDR_WIDTH-1 : 0] mem_axi_awaddr;
wire [7 : 0] mem_axi_awlen;
wire [2 : 0] mem_axi_awsize;
wire [1 : 0] mem_axi_awburst;
wire mem_axi_awlock;
wire [3 : 0] mem_axi_awcache;
wire [2 : 0] mem_axi_awprot;
wire [3 : 0] mem_axi_awqos;
wire [3 : 0] mem_axi_awregion;
wire [C_M_AXI_AWUSER_WIDTH-1 : 0] mem_axi_awuser;
wire mem_axi_awvalid;
wire mem_axi_awready;
wire [C_M_AXI_ysyx_040991_DATA_WIDTH-1 : 0] mem_axi_wdata;
wire [C_M_AXI_ysyx_040991_DATA_WIDTH/8-1 : 0] mem_axi_wstrb;
wire mem_axi_wlast;
wire [C_M_AXI_WUSER_WIDTH-1 : 0] mem_axi_wuser;
wire mem_axi_wvalid;
wire mem_axi_wready;
wire [C_M_AXI_ID_WIDTH-1 : 0] mem_axi_bid;
wire [1 : 0] mem_axi_bresp;
wire [C_M_AXI_BUSER_WIDTH-1 : 0] mem_axi_buser;
wire mem_axi_bvalid;
wire mem_axi_bready;
wire [C_M_AXI_ID_WIDTH-1 : 0] mem_axi_arid;
wire [C_M_AXI_ADDR_WIDTH-1 : 0] mem_axi_araddr;
wire [7 : 0] mem_axi_arlen;
wire [2 : 0] mem_axi_arsize;
wire [1 : 0] mem_axi_arburst;
wire mem_axi_arlock;
wire [3 : 0] mem_axi_arcache;
wire [2 : 0] mem_axi_arprot;
wire [3 : 0] mem_axi_arqos;
wire [3 : 0] mem_axi_arregion;
wire [C_M_AXI_ARUSER_WIDTH-1 : 0] mem_axi_aruser;
wire mem_axi_arvalid;
wire mem_axi_arready;
wire [C_M_AXI_ID_WIDTH-1 : 0] mem_axi_rid;
wire [C_M_AXI_ysyx_040991_DATA_WIDTH-1 : 0] mem_axi_rdata;
wire [1 : 0] mem_axi_rresp;
wire mem_axi_rlast;
wire [C_M_AXI_RUSER_WIDTH-1 : 0] mem_axi_ruser;
wire mem_axi_rvalid;
wire mem_axi_rready;
wire [C_M_AXI_ID_WIDTH-1 : 0] clint_axi_awid;
wire [C_M_AXI_ADDR_WIDTH-1 : 0] clint_axi_awaddr;
wire [7 : 0] clint_axi_awlen;
wire [2 : 0] clint_axi_awsize;
wire [1 : 0] clint_axi_awburst;
wire clint_axi_awlock;
wire [3 : 0] clint_axi_awcache;
wire [2 : 0] clint_axi_awprot;
wire [3 : 0] clint_axi_awqos;
wire [3 : 0] clint_axi_awregion;
wire [C_M_AXI_AWUSER_WIDTH-1 : 0] clint_axi_awuser;
wire clint_axi_awvalid;
wire clint_axi_awready;
wire [C_M_AXI_ysyx_040991_DATA_WIDTH-1 : 0] clint_axi_wdata;
wire [C_M_AXI_ysyx_040991_DATA_WIDTH/8-1 : 0] clint_axi_wstrb;
wire clint_axi_wlast;
wire [C_M_AXI_WUSER_WIDTH-1 : 0] clint_axi_wuser;
wire clint_axi_wvalid;
wire clint_axi_wready;
wire [C_M_AXI_ID_WIDTH-1 : 0] clint_axi_bid;
wire [1 : 0] clint_axi_bresp;
wire [C_M_AXI_BUSER_WIDTH-1 : 0] clint_axi_buser;
wire clint_axi_bvalid;
wire clint_axi_bready;
wire [C_M_AXI_ID_WIDTH-1 : 0] clint_axi_arid;
wire [C_M_AXI_ADDR_WIDTH-1 : 0] clint_axi_araddr;
wire [7 : 0] clint_axi_arlen;
wire [2 : 0] clint_axi_arsize;
wire [1 : 0] clint_axi_arburst;
wire clint_axi_arlock;
wire [3 : 0] clint_axi_arcache;
wire [2 : 0] clint_axi_arprot;
wire [3 : 0] clint_axi_arqos;
wire [3 : 0] clint_axi_arregion;
wire [C_M_AXI_ARUSER_WIDTH-1 : 0] clint_axi_aruser;
wire clint_axi_arvalid;
wire clint_axi_arready;
wire [C_M_AXI_ID_WIDTH-1 : 0] clint_axi_rid;
wire [C_M_AXI_ysyx_040991_DATA_WIDTH-1 : 0] clint_axi_rdata;
wire [1 : 0] clint_axi_rresp;
wire clint_axi_rlast;
wire [C_M_AXI_RUSER_WIDTH-1 : 0] clint_axi_ruser;
wire clint_axi_rvalid;
wire clint_axi_rready;
wire timer_interrupt;
wire io_slave_awlock ;
wire [3:0] io_slave_awcache ;
wire [2:0] io_slave_awprot ;
wire [3:0] io_slave_awqos ;
wire [3:0] io_slave_awregion ;
wire io_slave_awuser ;
wire io_slave_arlock ;
wire [3:0] io_slave_arcache ;
wire [2:0] io_slave_arprot ;
wire [3:0] io_slave_arqos ;
wire [3:0] io_slave_arregion ;
wire io_slave_awuser ;
wire io_slave_wuser;
wire io_slave_buser;
wire io_slave_aruser;
wire io_slave_ruser;
assign io_slave_wuser = 'b0;
assign io_slave_aruser = 'b0;
assign io_slave_awlock = 'b0;
assign io_slave_awcache = 'b0;
assign io_slave_awprot = 'b0;
assign io_slave_awqos = 'b0;
assign io_slave_awregion = 'b0;
assign io_slave_awuser = 'b0;
assign io_slave_arlock = 'b0;
assign io_slave_arcache = 'b0;
assign io_slave_arprot = 'b0;
assign io_slave_arqos = 'b0;
assign io_slave_arregion = 'b0;
ysyx_040991_npc_top u_npc_top(
.clk (clock ),
.rst (reset ),
.interrupt_taken (timer_interrupt ),
.mem_axi_awid (mem_axi_awid ),
.mem_axi_awaddr (mem_axi_awaddr ),
.mem_axi_awlen (mem_axi_awlen ),
.mem_axi_awsize (mem_axi_awsize ),
.mem_axi_awburst (mem_axi_awburst ),
.mem_axi_awlock (mem_axi_awlock ),
.mem_axi_awcache (mem_axi_awcache ),
.mem_axi_awprot (mem_axi_awprot ),
.mem_axi_awqos (mem_axi_awqos ),
.mem_axi_awregion (mem_axi_awregion),
.mem_axi_awuser (mem_axi_awuser ),
.mem_axi_awvalid (mem_axi_awvalid ),
.mem_axi_awready (mem_axi_awready ),
.mem_axi_wdata (mem_axi_wdata ),
.mem_axi_wstrb (mem_axi_wstrb ),
.mem_axi_wlast (mem_axi_wlast ),
.mem_axi_wuser (mem_axi_wuser ),
.mem_axi_wvalid (mem_axi_wvalid ),
.mem_axi_wready (mem_axi_wready ),
.mem_axi_bid (mem_axi_bid ),
.mem_axi_bresp (mem_axi_bresp ),
.mem_axi_buser (mem_axi_buser ),
.mem_axi_bvalid (mem_axi_bvalid ),
.mem_axi_bready (mem_axi_bready ),
.mem_axi_arid (mem_axi_arid ),
.mem_axi_araddr (mem_axi_araddr ),
.mem_axi_arlen (mem_axi_arlen ),
.mem_axi_arsize (mem_axi_arsize ),
.mem_axi_arburst (mem_axi_arburst ),
.mem_axi_arlock (mem_axi_arlock ),
.mem_axi_arcache (mem_axi_arcache ),
.mem_axi_arprot (mem_axi_arprot ),
.mem_axi_arqos (mem_axi_arqos ),
.mem_axi_arregion (mem_axi_arregion),
.mem_axi_aruser (mem_axi_aruser ),
.mem_axi_arvalid (mem_axi_arvalid ),
.mem_axi_arready (mem_axi_arready ),
.mem_axi_rid (mem_axi_rid ),
.mem_axi_rdata (mem_axi_rdata ),
.mem_axi_rresp (mem_axi_rresp ),
.mem_axi_rlast (mem_axi_rlast ),
.mem_axi_ruser (mem_axi_ruser ),
.mem_axi_rvalid (mem_axi_rvalid ),
.mem_axi_rready (mem_axi_rready ),
.io_slave_awid (io_slave_awid ),
.io_slave_awaddr (io_slave_awaddr ),
.io_slave_awlen (io_slave_awlen ),
.io_slave_awsize (io_slave_awsize ),
.io_slave_awburst (io_slave_awburst ),
.io_slave_awlock (io_slave_awlock ),
.io_slave_awcache (io_slave_awcache ),
.io_slave_awprot (io_slave_awprot ),
.io_slave_awqos (io_slave_awqos ),
.io_slave_awregion (io_slave_awregion ),
.io_slave_awuser (io_slave_awuser ),
.io_slave_awvalid (io_slave_awvalid ),
.io_slave_awready (io_slave_awready ),
.io_slave_wdata (io_slave_wdata ),
.io_slave_wstrb (io_slave_wstrb ),
.io_slave_wlast (io_slave_wlast ),
.io_slave_wuser (io_slave_wuser ),
.io_slave_wvalid (io_slave_wvalid ),
.io_slave_wready (io_slave_wready ),
.io_slave_bid (io_slave_bid ),
.io_slave_bresp (io_slave_bresp ),
.io_slave_buser (io_slave_buser ),
.io_slave_bvalid (io_slave_bvalid ),
.io_slave_bready (io_slave_bready ),
.io_slave_arid (io_slave_arid ),
.io_slave_araddr (io_slave_araddr ),
.io_slave_arlen (io_slave_arlen ),
.io_slave_arsize (io_slave_arsize ),
.io_slave_arburst (io_slave_arburst ),
.io_slave_arlock (io_slave_arlock ),
.io_slave_arcache (io_slave_arcache ),
.io_slave_arprot (io_slave_arprot ),
.io_slave_arqos (io_slave_arqos ),
.io_slave_arregion (io_slave_arregion ),
.io_slave_aruser (io_slave_aruser ),
.io_slave_arvalid (io_slave_arvalid ),
.io_slave_arready (io_slave_arready ),
.io_slave_rid (io_slave_rid ),
.io_slave_rdata (io_slave_rdata ),
.io_slave_rresp (io_slave_rresp ),
.io_slave_rlast (io_slave_rlast ),
.io_slave_ruser (io_slave_ruser ),
.io_slave_rvalid (io_slave_rvalid ),
.io_slave_rready (io_slave_rready ),
.icache_ram0_bank0_Q (io_sram0_rdata ),
.icache_ram0_bank0_CEN (io_sram0_cen ),
.icache_ram0_bank0_WEN (io_sram0_wen ),
.icache_ram0_bank0_BWEN (io_sram0_wmask ),
.icache_ram0_bank0_A (io_sram0_addr ),
.icache_ram0_bank0_D (io_sram0_wdata ),
.icache_ram0_bank1_Q (io_sram1_rdata ),
.icache_ram0_bank1_CEN (io_sram1_cen ),
.icache_ram0_bank1_WEN (io_sram1_wen ),
.icache_ram0_bank1_BWEN (io_sram1_wmask ),
.icache_ram0_bank1_A (io_sram1_addr ),
.icache_ram0_bank1_D (io_sram1_wdata ),
.icache_ram1_bank0_Q (io_sram2_rdata ),
.icache_ram1_bank0_CEN (io_sram2_cen ),
.icache_ram1_bank0_WEN (io_sram2_wen ),
.icache_ram1_bank0_BWEN (io_sram2_wmask ),
.icache_ram1_bank0_A (io_sram2_addr ),
.icache_ram1_bank0_D (io_sram2_wdata ),
.icache_ram1_bank1_Q (io_sram3_rdata ),
.icache_ram1_bank1_CEN (io_sram3_cen ),
.icache_ram1_bank1_WEN (io_sram3_wen ),
.icache_ram1_bank1_BWEN (io_sram3_wmask ),
.icache_ram1_bank1_A (io_sram3_addr ),
.icache_ram1_bank1_D (io_sram3_wdata ),
.dcache_ram0_bank0_Q (io_sram4_rdata ),
.dcache_ram0_bank0_CEN (io_sram4_cen ),
.dcache_ram0_bank0_WEN (io_sram4_wen ),
.dcache_ram0_bank0_BWEN (io_sram4_wmask ),
.dcache_ram0_bank0_A (io_sram4_addr ),
.dcache_ram0_bank0_D (io_sram4_wdata ),
.dcache_ram0_bank1_Q (io_sram5_rdata ),
.dcache_ram0_bank1_CEN (io_sram5_cen ),
.dcache_ram0_bank1_WEN (io_sram5_wen ),
.dcache_ram0_bank1_BWEN (io_sram5_wmask ),
.dcache_ram0_bank1_A (io_sram5_addr ),
.dcache_ram0_bank1_D (io_sram5_wdata ),
.dcache_ram1_bank0_Q (io_sram6_rdata ),
.dcache_ram1_bank0_CEN (io_sram6_cen ),
.dcache_ram1_bank0_WEN (io_sram6_wen ),
.dcache_ram1_bank0_BWEN (io_sram6_wmask ),
.dcache_ram1_bank0_A (io_sram6_addr ),
.dcache_ram1_bank0_D (io_sram6_wdata ),
.dcache_ram1_bank1_Q (io_sram7_rdata ),
.dcache_ram1_bank1_CEN (io_sram7_cen ),
.dcache_ram1_bank1_WEN (io_sram7_wen ),
.dcache_ram1_bank1_BWEN (io_sram7_wmask ),
.dcache_ram1_bank1_A (io_sram7_addr ),
.dcache_ram1_bank1_D (io_sram7_wdata )
);
wire io_master_awlock ;
wire [3:0] io_master_awcache ;
wire [2:0] io_master_awprot ;
wire [3:0] io_master_awqos ;
wire [3:0] io_master_awregion ;
wire io_master_awuser ;
wire io_master_arlock ;
wire [3:0] io_master_arcache ;
wire [2:0] io_master_arprot ;
wire [3:0] io_master_arqos ;
wire [3:0] io_master_arregion ;
wire io_master_awuser ;
wire io_master_wuser;
wire io_master_buser;
wire io_master_aruser;
wire io_master_ruser;
assign io_master_buser = 'b0;
assign io_master_ruser = 'b0;
ysyx_040991_axi_xbar
#(
.ysyx_040991_DATA_WIDTH (64 ),
.ADDR_WIDTH (32 ),
.STRB_WIDTH (8 ),
.S_ID_WIDTH (4 ),
.M_ID_WIDTH (4 )
)
u_axi_xbar(
.clk (clock ),
.rst (reset ),
.io_master_awid (io_master_awid ),
.io_master_awaddr (io_master_awaddr ),
.io_master_awlen (io_master_awlen ),
.io_master_awsize (io_master_awsize ),
.io_master_awburst (io_master_awburst ),
.io_master_awlock (io_master_awlock ),
.io_master_awcache (io_master_awcache ),
.io_master_awprot (io_master_awprot ),
.io_master_awqos (io_master_awqos ),
.io_master_awregion (io_master_awregion ),
.io_master_awuser (io_master_awuser ),
.io_master_awvalid (io_master_awvalid ),
.io_master_awready (io_master_awready ),
.io_master_wdata (io_master_wdata ),
.io_master_wstrb (io_master_wstrb ),
.io_master_wlast (io_master_wlast ),
.io_master_wuser (io_master_wuser ),
.io_master_wvalid (io_master_wvalid ),
.io_master_wready (io_master_wready ),
.io_master_bid (io_master_bid ),
.io_master_bresp (io_master_bresp ),
.io_master_buser (io_master_buser ),
.io_master_bvalid (io_master_bvalid ),
.io_master_bready (io_master_bready ),
.io_master_arid (io_master_arid ),
.io_master_araddr (io_master_araddr ),
.io_master_arlen (io_master_arlen ),
.io_master_arsize (io_master_arsize ),
.io_master_arburst (io_master_arburst ),
.io_master_arlock (io_master_arlock ),
.io_master_arcache (io_master_arcache ),
.io_master_arprot (io_master_arprot ),
.io_master_arqos (io_master_arqos ),
.io_master_arregion (io_master_arregion ),
.io_master_aruser (io_master_aruser ),
.io_master_arvalid (io_master_arvalid ),
.io_master_arready (io_master_arready ),
.io_master_rid (io_master_rid ),
.io_master_rdata (io_master_rdata ),
.io_master_rresp (io_master_rresp ),
.io_master_rlast (io_master_rlast ),
.io_master_ruser (io_master_ruser ),
.io_master_rvalid (io_master_rvalid ),
.io_master_rready (io_master_rready ),
.clint_axi_awid (clint_axi_awid ),
.clint_axi_awaddr (clint_axi_awaddr ),
.clint_axi_awlen (clint_axi_awlen ),
.clint_axi_awsize (clint_axi_awsize ),
.clint_axi_awburst (clint_axi_awburst ),
.clint_axi_awlock (clint_axi_awlock ),
.clint_axi_awcache (clint_axi_awcache ),
.clint_axi_awprot (clint_axi_awprot ),
.clint_axi_awqos (clint_axi_awqos ),
.clint_axi_awregion (clint_axi_awregion ),
.clint_axi_awuser (clint_axi_awuser ),
.clint_axi_awvalid (clint_axi_awvalid ),
.clint_axi_awready (clint_axi_awready ),
.clint_axi_wdata (clint_axi_wdata ),
.clint_axi_wstrb (clint_axi_wstrb ),
.clint_axi_wlast (clint_axi_wlast ),
.clint_axi_wuser (clint_axi_wuser ),
.clint_axi_wvalid (clint_axi_wvalid ),
.clint_axi_wready (clint_axi_wready ),
.clint_axi_bid (clint_axi_bid ),
.clint_axi_bresp (clint_axi_bresp ),
.clint_axi_buser (clint_axi_buser ),
.clint_axi_bvalid (clint_axi_bvalid ),
.clint_axi_bready (clint_axi_bready ),
.clint_axi_arid (clint_axi_arid ),
.clint_axi_araddr (clint_axi_araddr ),
.clint_axi_arlen (clint_axi_arlen ),
.clint_axi_arsize (clint_axi_arsize ),
.clint_axi_arburst (clint_axi_arburst ),
.clint_axi_arlock (clint_axi_arlock ),
.clint_axi_arcache (clint_axi_arcache ),
.clint_axi_arprot (clint_axi_arprot ),
.clint_axi_arqos (clint_axi_arqos ),
.clint_axi_arregion (clint_axi_arregion ),
.clint_axi_aruser (clint_axi_aruser ),
.clint_axi_arvalid (clint_axi_arvalid ),
.clint_axi_arready (clint_axi_arready ),
.clint_axi_rid (clint_axi_rid ),
.clint_axi_rdata (clint_axi_rdata ),
.clint_axi_rresp (clint_axi_rresp ),
.clint_axi_rlast (clint_axi_rlast ),
.clint_axi_ruser (clint_axi_ruser ),
.clint_axi_rvalid (clint_axi_rvalid ),
.clint_axi_rready (clint_axi_rready ),
.m00_axi_awid (mem_axi_awid ),
.m00_axi_awaddr (mem_axi_awaddr ),
.m00_axi_awlen (mem_axi_awlen ),
.m00_axi_awsize (mem_axi_awsize ),
.m00_axi_awburst (mem_axi_awburst ),
.m00_axi_awlock (mem_axi_awlock ),
.m00_axi_awcache (mem_axi_awcache ),
.m00_axi_awprot (mem_axi_awprot ),
.m00_axi_awqos (mem_axi_awqos ),
.m00_axi_awregion (mem_axi_awregion ),
.m00_axi_awuser (mem_axi_awuser ),
.m00_axi_awvalid (mem_axi_awvalid ),
.m00_axi_awready (mem_axi_awready ),
.m00_axi_wdata (mem_axi_wdata ),
.m00_axi_wstrb (mem_axi_wstrb ),
.m00_axi_wlast (mem_axi_wlast ),
.m00_axi_wuser (mem_axi_wuser ),
.m00_axi_wvalid (mem_axi_wvalid ),
.m00_axi_wready (mem_axi_wready ),
.m00_axi_bid (mem_axi_bid ),
.m00_axi_bresp (mem_axi_bresp ),
.m00_axi_buser (mem_axi_buser ),
.m00_axi_bvalid (mem_axi_bvalid ),
.m00_axi_bready (mem_axi_bready ),
.m00_axi_arid (mem_axi_arid ),
.m00_axi_araddr (mem_axi_araddr ),
.m00_axi_arlen (mem_axi_arlen ),
.m00_axi_arsize (mem_axi_arsize ),
.m00_axi_arburst (mem_axi_arburst ),
.m00_axi_arlock (mem_axi_arlock ),
.m00_axi_arcache (mem_axi_arcache ),
.m00_axi_arprot (mem_axi_arprot ),
.m00_axi_arqos (mem_axi_arqos ),
.m00_axi_arregion (mem_axi_arregion ),
.m00_axi_aruser (mem_axi_aruser ),
.m00_axi_arvalid (mem_axi_arvalid ),
.m00_axi_arready (mem_axi_arready ),
.m00_axi_rid (mem_axi_rid ),
.m00_axi_rdata (mem_axi_rdata ),
.m00_axi_rresp (mem_axi_rresp ),
.m00_axi_rlast (mem_axi_rlast ),
.m00_axi_ruser (mem_axi_ruser ),
.m00_axi_rvalid (mem_axi_rvalid ),
.m00_axi_rready (mem_axi_rready )
);
ysyx_040991_axi_clint
#(
.ysyx_040991_DATA_WIDTH (64 ),
.ADDR_WIDTH (32 ),
.STRB_WIDTH (8 ),
.ID_WIDTH (4 )
)
u_axi_clint(
.clk (clock ),
.rst (reset ),
.s_axi_awid (clint_axi_awid ),
.s_axi_awaddr (clint_axi_awaddr ),
.s_axi_awlen (clint_axi_awlen ),
.s_axi_awsize (clint_axi_awsize ),
.s_axi_awburst (clint_axi_awburst ),
.s_axi_awlock (clint_axi_awlock ),
.s_axi_awcache (clint_axi_awcache ),
.s_axi_awprot (clint_axi_awprot ),
.s_axi_awqos (clint_axi_awqos ),
.s_axi_awregion (clint_axi_awregion ),
.s_axi_awuser (clint_axi_awuser ),
.s_axi_awvalid (clint_axi_awvalid ),
.s_axi_awready (clint_axi_awready ),
.s_axi_wdata (clint_axi_wdata ),
.s_axi_wstrb (clint_axi_wstrb ),
.s_axi_wlast (clint_axi_wlast ),
.s_axi_wuser (clint_axi_wuser ),
.s_axi_wvalid (clint_axi_wvalid ),
.s_axi_wready (clint_axi_wready ),
.s_axi_bid (clint_axi_bid ),
.s_axi_bresp (clint_axi_bresp ),
.s_axi_buser (clint_axi_buser ),
.s_axi_bvalid (clint_axi_bvalid ),
.s_axi_bready (clint_axi_bready ),
.s_axi_arid (clint_axi_arid ),
.s_axi_araddr (clint_axi_araddr ),
.s_axi_arlen (clint_axi_arlen ),
.s_axi_arsize (clint_axi_arsize ),
.s_axi_arburst (clint_axi_arburst ),
.s_axi_arlock (clint_axi_arlock ),
.s_axi_arcache (clint_axi_arcache ),
.s_axi_arprot (clint_axi_arprot ),
.s_axi_arqos (clint_axi_arqos ),
.s_axi_arregion (clint_axi_arregion ),
.s_axi_aruser (clint_axi_aruser ),
.s_axi_arvalid (clint_axi_arvalid ),
.s_axi_arready (clint_axi_arready ),
.s_axi_rid (clint_axi_rid ),
.s_axi_rdata (clint_axi_rdata ),
.s_axi_rresp (clint_axi_rresp ),
.s_axi_rlast (clint_axi_rlast ),
.s_axi_ruser (clint_axi_ruser ),
.s_axi_rvalid (clint_axi_rvalid ),
.s_axi_rready (clint_axi_rready ),
.timer_interrupt (timer_interrupt )
);
endmodule
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。