├── README.md ├── alu.v ├── axi_bridge.v ├── cache.v ├── cpu_core.v ├── exe_stage.v ├── id_stage.v ├── if_stage.v ├── mem_stage.v ├── mycpu.h ├── mycpu_top.v ├── regcsr.v ├── regfile.v ├── tlb.v ├── tools.v └── wb_stage.v /README.md: -------------------------------------------------------------------------------- 1 | # UCAS_CAlab 2 | 3 | A 5-stage sequential LoongArch CPU built with Verilog. 4 | 5 | Project of Computer Architecture Lab @UCAS. 6 | 7 | Some of the documents are [here](https://josephqiu.notion.site/7c4cea2934a34752a09d344eb25ab96b?v=94987745cbbf4052b3efd212d0fc2637). 8 | 9 | Also some code are extremely shitty and unreliable (sorry Louise i guess we can agree on this). For example, Lab 9 if I remembered it right. 10 | -------------------------------------------------------------------------------- /alu.v: -------------------------------------------------------------------------------- 1 | module alu( 2 | input clk, 3 | input reset, 4 | input [18:0] alu_op, 5 | input [31:0] alu_src1, 6 | input [31:0] alu_src2, 7 | output div_ready_go, 8 | output [31:0] alu_result 9 | ); 10 | 11 | wire op_add; //add operation 12 | wire op_sub; //sub operation 13 | wire op_slt; //signed compared and set less than 14 | wire op_sltu; //unsigned compared and set less than 15 | wire op_and; //bitwise and 16 | wire op_nor; //bitwise nor 17 | wire op_or; //bitwise or 18 | wire op_xor; //bitwise xor 19 | wire op_sll; //logic left shift 20 | wire op_srl; //logic right shift 21 | wire op_sra; //arithmetic right shift 22 | wire op_lui; //Load Upper Immediate 23 | 24 | wire op_mul; //multiply signed/unsigned low 32 25 | wire op_mulh; //multiply signed high 32 26 | wire op_mulhu; //multiply unsigned high 32 27 | wire op_div; //division quotient 28 | wire op_divu; //division unsigned quotient 29 | wire op_mod; //division remainder 30 | wire op_modu; //division unsigned remainder 31 | 32 | // control code decomposition 33 | assign op_add = alu_op[ 0]; 34 | assign op_sub = alu_op[ 1]; 35 | assign op_slt = alu_op[ 2]; 36 | assign op_sltu = alu_op[ 3]; 37 | assign op_and = alu_op[ 4]; 38 | assign op_nor = alu_op[ 5]; 39 | assign op_or = alu_op[ 6]; 40 | assign op_xor = alu_op[ 7]; 41 | assign op_sll = alu_op[ 8]; 42 | assign op_srl = alu_op[ 9]; 43 | assign op_sra = alu_op[10]; 44 | assign op_lui = alu_op[11]; 45 | //Add in lab6 46 | assign op_mul = alu_op[12]; 47 | assign op_mulh = alu_op[13]; 48 | assign op_mulhu= alu_op[14]; 49 | assign op_div = alu_op[15]; 50 | assign op_divu = alu_op[16]; 51 | assign op_mod = alu_op[17]; 52 | assign op_modu = alu_op[18]; 53 | 54 | wire [31:0] add_sub_result; 55 | wire [31:0] slt_result; 56 | wire [31:0] sltu_result; 57 | wire [31:0] and_result; 58 | wire [31:0] nor_result; 59 | wire [31:0] or_result; 60 | wire [31:0] xor_result; 61 | wire [31:0] lui_result; 62 | wire [31:0] sll_result; 63 | wire [63:0] sr64_result; 64 | wire [31:0] sr_result; 65 | //Add in lab6 66 | wire [65:0] mul_result; //33*33 for mulh.w, mulh.wu 67 | wire [32:0] mul_a; 68 | wire [32:0] mul_b; 69 | 70 | // 32-bit adder 71 | wire [31:0] adder_a; 72 | wire [31:0] adder_b; 73 | wire adder_cin; 74 | wire [31:0] adder_result; 75 | wire adder_cout; 76 | 77 | assign adder_a = alu_src1; 78 | assign adder_b = (op_sub | op_slt | op_sltu) ? ~alu_src2 : alu_src2; //src1 - src2 rj-rk 79 | assign adder_cin = (op_sub | op_slt | op_sltu) ? 1'b1 : 1'b0; 80 | assign {adder_cout, adder_result} = adder_a + adder_b + adder_cin; 81 | 82 | // ADD, SUB result 83 | assign add_sub_result = adder_result; 84 | 85 | // SLT result 86 | assign slt_result[31:1] = 31'b0; //rj < rk 1 87 | assign slt_result[0] = (alu_src1[31] & ~alu_src2[31]) 88 | | ((alu_src1[31] ~^ alu_src2[31]) & adder_result[31]); 89 | 90 | // SLTU result 91 | assign sltu_result[31:1] = 31'b0; 92 | assign sltu_result[0] = ~adder_cout; 93 | 94 | // bitwise operation 95 | assign and_result = alu_src1 & alu_src2; 96 | assign or_result = alu_src1 | alu_src2; 97 | assign nor_result = ~or_result; 98 | assign xor_result = alu_src1 ^ alu_src2; 99 | assign lui_result = alu_src2;//{alu_src2[14:0], alu_src2[19:15], 12'b0}; 100 | 101 | // SLL result 102 | assign sll_result = alu_src1 << alu_src2[4:0]; //rj << i5 103 | 104 | // SRL, SRA result 105 | assign sr64_result = {{32{op_sra & alu_src1[31]}}, alu_src1[31:0]} >> alu_src2[4:0]; //rj >> i5 106 | 107 | assign sr_result = sr64_result[31:0]; 108 | 109 | assign mul_a = {33{op_mulhu}} & {1'b0,alu_src1} | {33{~op_mulhu}} & {alu_src1[31],alu_src1}; 110 | assign mul_b = {33{op_mulhu}} & {1'b0,alu_src2} | {33{~op_mulhu}} & {alu_src2[31],alu_src2}; 111 | assign mul_result = $signed(mul_a) * $signed(mul_b); 112 | 113 | //assign signed_div_result = ~(slt_result[0] && (alu_src1[31]==alu_src2[31])) ? signed_div_result : 64'b0; 114 | 115 | wire [3:0] div_op = alu_op[18:15]; 116 | wire [31:0] div_src1 = alu_src1; 117 | wire [31:0] div_src2 = alu_src2; 118 | wire [31:0] div_final_result; 119 | wire div_running; 120 | wire op_div; 121 | wire op_divu; 122 | wire op_mod; 123 | wire op_modu; 124 | 125 | assign op_div = div_op[0]; 126 | assign op_divu = div_op[1]; 127 | assign op_mod = div_op[2]; 128 | assign op_modu = div_op[3]; 129 | 130 | wire [63:0] div_result; 131 | wire [63:0] div_u_result; 132 | 133 | wire div_src_ready; 134 | wire div_ans_valid; 135 | wire div_divisor_ready; 136 | wire div_dividend_ready; 137 | wire div_work; 138 | wire div_u_src_ready; 139 | wire div_u_ans_valid; 140 | wire div_u_divisor_ready; 141 | wire div_u_dividend_ready; 142 | wire div_u_work; 143 | 144 | reg div_src_valid; 145 | reg div_u_src_valid; 146 | reg div_state; 147 | 148 | assign div_work = op_div | op_mod; 149 | assign div_src_ready = div_divisor_ready & div_dividend_ready; 150 | assign div_u_work = op_divu | op_modu; 151 | assign div_u_src_ready = div_u_divisor_ready & div_u_dividend_ready; 152 | assign div_running = div_work & ~div_ans_valid | div_u_work & ~div_u_ans_valid; 153 | assign div_ready_go = ~div_running; 154 | 155 | always @ (posedge clk) begin 156 | if(reset) begin 157 | div_src_valid <= 1'b0; 158 | end 159 | else if (~div_state & div_work) begin 160 | div_src_valid <= 1'b1; 161 | end 162 | else if (div_src_valid & div_src_ready) begin 163 | div_src_valid <= 1'b0; 164 | end 165 | end 166 | 167 | always @ (posedge clk) begin 168 | if(reset) begin 169 | div_u_src_valid <= 1'b0; 170 | end 171 | else if (~div_state & div_u_work) begin 172 | div_u_src_valid <= 1'b1; 173 | end 174 | else if (div_u_src_valid & div_u_src_ready) begin 175 | div_u_src_valid <= 1'b0; 176 | end 177 | end 178 | 179 | always @ (posedge clk) begin 180 | if(reset) begin 181 | div_state <= 1'b0; 182 | end 183 | else if (~div_state & (div_work | div_u_work)) begin 184 | div_state <= 1'b1; 185 | end 186 | else if (div_ans_valid | div_u_ans_valid) begin 187 | div_state <= 1'b0; 188 | end 189 | end 190 | 191 | mydiv mydiv( 192 | .s_axis_divisor_tdata(div_src2), 193 | .s_axis_dividend_tdata(div_src1), 194 | .s_axis_divisor_tvalid(div_src_valid), 195 | .s_axis_dividend_tvalid(div_src_valid), 196 | .s_axis_divisor_tready(div_divisor_ready), 197 | .s_axis_dividend_tready(div_dividend_ready), 198 | .aclk(clk), 199 | .m_axis_dout_tdata(div_result), 200 | .m_axis_dout_tvalid(div_ans_valid) 201 | ); 202 | 203 | my_unsigned_div my_unsigned_div( 204 | .s_axis_divisor_tdata(div_src2), 205 | .s_axis_dividend_tdata(div_src1), 206 | .s_axis_divisor_tvalid(div_u_src_valid), 207 | .s_axis_dividend_tvalid(div_u_src_valid), 208 | .s_axis_divisor_tready(div_u_divisor_ready), 209 | .s_axis_dividend_tready(div_u_dividend_ready), 210 | .aclk(clk), 211 | .m_axis_dout_tdata(div_u_result), 212 | .m_axis_dout_tvalid(div_u_ans_valid) 213 | ); 214 | 215 | assign alu_result = ({32{op_add|op_sub}} & add_sub_result) 216 | | ({32{op_slt }} & slt_result) 217 | | ({32{op_sltu }} & sltu_result) 218 | | ({32{op_and }} & and_result) 219 | | ({32{op_nor }} & nor_result) 220 | | ({32{op_or }} & or_result) 221 | | ({32{op_xor }} & xor_result) 222 | | ({32{op_lui }} & lui_result) 223 | | ({32{op_sll }} & sll_result) 224 | | ({32{op_srl|op_sra}} & sr_result) 225 | | ({32{op_mul }} & mul_result[31:0]) //the low 32 226 | | ({32{op_mulh|op_mulhu}} & mul_result[63:32]) //the high 32 227 | | ({32{op_div }} & div_result[63:32]) //the high 32 for quotient 228 | | ({32{op_divu }} & div_u_result[63:32]) 229 | | ({32{op_mod }} & div_result[31:0]) //the low 32 for remainder 230 | | ({32{op_modu }} & div_u_result[31:0]); 231 | 232 | 233 | endmodule -------------------------------------------------------------------------------- /axi_bridge.v: -------------------------------------------------------------------------------- 1 | module axi_bridge( 2 | input aclk, 3 | input aresetn, 4 | // read request channel 5 | output [ 3:0] arid,//inst: 0,data: 1 6 | output [31:0] araddr, 7 | output [ 7:0] arlen,//0 8 | output [ 2:0] arsize, 9 | output [ 1:0] arburst,//0b01 10 | output [ 1:0] arlock,//0 11 | output [ 3:0] arcache,//0 12 | output [ 2:0] arprot,//0 13 | output arvalid,//read address valid 14 | input arready,//read address valid 15 | // read respond channel 16 | input [ 3:0] rid, 17 | input [31:0] rdata, 18 | input [ 1:0] rresp,//ignore 19 | input rlast,//ignore 20 | input rvalid,//read valid 21 | output rready,//read ready 22 | // write request channel 23 | output [ 3:0] awid,//1 24 | output [31:0] awaddr, 25 | output [ 7:0] awlen,//0 26 | output [ 2:0] awsize, 27 | output [ 1:0] awburst,//0b01 28 | output [ 1:0] awlock,//0 29 | output [ 3:0] awcache,//0 30 | output [ 2:0] awprot,//0 31 | output awvalid,//write address valid 32 | input awready,//write address valid 33 | // write data channel 34 | output [ 3:0] wid,//1 35 | output [31:0] wdata, 36 | output [ 3:0] wstrb,//WSTRB[n] corresponds to WDATA[(8n) + 7: (8n)]. 37 | output wlast,//1 38 | output wvalid, 39 | input wready, 40 | // write respond channel 41 | input [ 3:0] bid,//ignore 42 | input [ 1:0] bresp,//ignore 43 | input bvalid,//write response valid 44 | output bready,//write response ready 45 | // inst sram interface 46 | input inst_sram_req, 47 | input [ 3:0] inst_sram_wstrb, 48 | input [31:0] inst_sram_addr, 49 | input [31:0] inst_sram_wdata, 50 | output [31:0] inst_sram_rdata, 51 | input [ 1:0] inst_sram_size, 52 | output inst_sram_addr_ok, 53 | output inst_sram_data_ok, 54 | input inst_sram_wr,//1: write; 0: read 55 | // data sram interface 56 | input data_sram_req, 57 | input [ 3:0] data_sram_wstrb, 58 | input [31:0] data_sram_addr, 59 | input [31:0] data_sram_wdata, 60 | output [31:0] data_sram_rdata, 61 | input [ 1:0] data_sram_size, 62 | output data_sram_addr_ok, 63 | output data_sram_data_ok, 64 | input data_sram_wr 65 | ); 66 | 67 | 68 | /* ------------------- READ FSM ------------------- */ 69 | 70 | localparam READ_IDLE = 3'b001; 71 | localparam READ_RADDR = 3'b010; 72 | localparam READ_RDATA = 3'b100; 73 | 74 | reg [2:0] read_state; 75 | reg [2:0] read_next_state; 76 | 77 | // This reg indicate the state of reading from INST RAM 78 | // Because req don't last 79 | // Its opposite -> reading from DATA RAM 80 | reg reading_inst_ram; 81 | reg reading_data_ram; 82 | 83 | wire read_idle = read_state[0]; 84 | wire read_raddr = read_state[1]; 85 | wire read_rdata = read_state[2]; 86 | 87 | always @ (posedge aclk) begin 88 | if(~aresetn) begin 89 | read_state <= READ_IDLE; 90 | end 91 | else begin 92 | read_state <= read_next_state; 93 | end 94 | end 95 | 96 | always @ (*) begin 97 | case (read_state) 98 | READ_IDLE:begin 99 | if ((data_sram_req && ~data_sram_wr || inst_sram_req && ~inst_sram_wr) && write_idle) begin 100 | read_next_state = READ_RADDR; 101 | end 102 | else begin 103 | read_next_state = READ_IDLE; 104 | end 105 | end 106 | READ_RADDR:begin 107 | if (arvalid && arready) begin 108 | read_next_state = READ_RDATA; 109 | end 110 | else begin 111 | read_next_state = READ_RADDR; 112 | end 113 | end 114 | READ_RDATA:begin 115 | if (rready && rvalid) begin 116 | read_next_state = READ_IDLE; 117 | end 118 | else begin 119 | read_next_state = READ_RDATA; 120 | end 121 | end 122 | default: 123 | read_next_state = READ_IDLE; 124 | endcase 125 | end 126 | 127 | always @(posedge aclk) begin 128 | if (~aresetn) 129 | reading_inst_ram <= 1'b0; 130 | else if (~data_sram_req && read_idle && inst_sram_req && ~inst_sram_wr && write_idle) 131 | reading_inst_ram <= 1'b1; 132 | else if (read_rdata && rready && rvalid) 133 | reading_inst_ram <= 1'b0; 134 | end 135 | 136 | always @(posedge aclk) begin 137 | if (~aresetn) 138 | reading_data_ram <= 1'b0; 139 | else if (read_idle && data_sram_req && ~data_sram_wr && write_idle) 140 | reading_data_ram <= 1'b1; 141 | else if (read_rdata && rready && rvalid) 142 | reading_data_ram <= 1'b0; 143 | end 144 | 145 | /* ------------------- read request ------------------- */ 146 | assign inst_sram_addr_ok = arready && reading_inst_ram; 147 | assign inst_sram_data_ok = rvalid && reading_inst_ram; 148 | assign inst_sram_rdata = rdata; 149 | 150 | wire finish_two_handshake; 151 | 152 | reg [1:0] two_handshake; 153 | always @(posedge aclk) begin 154 | if (~aresetn) 155 | two_handshake <= 2'b00; 156 | else if (finish_two_handshake) 157 | two_handshake <= 2'b00; 158 | else if (awready || wready) 159 | two_handshake <= two_handshake + 1; 160 | end 161 | 162 | assign finish_two_handshake = two_handshake == 2'b10; 163 | 164 | // addr_ok: write transactions -> awready and wready (2 handshakes finished) 165 | // read transactions -> arready 166 | assign data_sram_addr_ok = finish_two_handshake || arready && reading_data_ram; 167 | assign data_sram_data_ok = rvalid && reading_data_ram || bvalid; 168 | assign data_sram_rdata = rdata; 169 | 170 | assign arid = read_raddr && reading_data_ram; 171 | assign araddr = {32{read_raddr && reading_inst_ram}} & inst_sram_addr | 172 | {32{read_raddr && reading_data_ram}} & data_sram_addr; 173 | assign arsize = {3{read_raddr && reading_inst_ram}} & {1'b0, inst_sram_size} | 174 | {3{read_raddr && reading_data_ram}} & {1'b0, data_sram_size}; 175 | assign arvalid = read_raddr; 176 | assign arlen = 8'b0; 177 | assign arburst = 2'b1; 178 | assign arlock = 2'b0; 179 | assign arcache = 4'b0; 180 | assign arprot = 3'b0; 181 | 182 | /* ------------------- read respond ------------------- */ 183 | assign rready = read_rdata; 184 | 185 | /* ------------------- WRITE FSM ------------------- */ 186 | 187 | localparam WRITE_IDLE = 4'b0001; 188 | localparam WRITE_WADDR = 4'b0010; 189 | localparam WRITE_WDATA = 4'b0100; 190 | localparam WRITE_BRESP = 4'b1000; 191 | reg [3:0] write_state; 192 | reg [3:0] write_next_state; 193 | 194 | wire write_idle = write_state[0]; 195 | wire write_waddr = write_state[1]; 196 | wire write_wdata = write_state[2]; 197 | wire write_bresp = write_state[3]; 198 | 199 | always @ (posedge aclk) begin 200 | if(~aresetn) begin 201 | write_state <= WRITE_IDLE; 202 | end 203 | else begin 204 | write_state <= write_next_state; 205 | end 206 | end 207 | 208 | always @ (*) begin 209 | case (write_state) 210 | WRITE_IDLE:begin 211 | if (data_sram_req && data_sram_wr) begin 212 | write_next_state = WRITE_WADDR; 213 | end 214 | else begin 215 | write_next_state = WRITE_IDLE; 216 | end 217 | end 218 | WRITE_WADDR:begin 219 | if (awvalid && awready) begin 220 | write_next_state = WRITE_WDATA; 221 | end 222 | else begin 223 | write_next_state = WRITE_WADDR; 224 | end 225 | end 226 | WRITE_WDATA:begin 227 | if (wvalid && wready) begin 228 | write_next_state = WRITE_BRESP; 229 | end 230 | else begin 231 | write_next_state = WRITE_WDATA; 232 | end 233 | end 234 | WRITE_BRESP:begin 235 | if (bvalid && bready) begin 236 | write_next_state = WRITE_IDLE; 237 | end 238 | else begin 239 | write_next_state = WRITE_BRESP; 240 | end 241 | end 242 | default: 243 | write_next_state = WRITE_IDLE; 244 | endcase 245 | end 246 | 247 | /* ------------------- write request ------------------- */ 248 | 249 | assign awaddr = {32{write_waddr}} & data_sram_addr; 250 | assign awsize = {3{write_waddr}} & {1'b0, data_sram_size}; 251 | assign awvalid = write_waddr; 252 | assign awid = 4'b1; 253 | assign awlen = 8'b0; 254 | assign awburst = 2'b1; 255 | assign awlock = 2'b0; 256 | assign awcache = 4'b0; 257 | assign awprot = 3'b0; 258 | 259 | /* ------------------- write data ------------------- */ 260 | assign wdata = {32{write_wdata}} & data_sram_wdata; 261 | assign wstrb = {4{write_wdata}} & data_sram_wstrb; 262 | assign wvalid = write_wdata; 263 | assign wid = 4'b1; 264 | assign wlast = 1'b1; 265 | 266 | /* ------------------- write respond ------------------- */ 267 | assign bready = write_bresp; 268 | 269 | endmodule -------------------------------------------------------------------------------- /cache.v: -------------------------------------------------------------------------------- 1 | module cache ( 2 | input clk_g, 3 | input resetn, 4 | // CPU Interface 5 | input valid, 6 | input op, //1: write, 0: read 7 | input [ 7:0] index, 8 | input [19:0] tag, 9 | input [ 3:0] offset, 10 | input [ 3:0] wstrb, 11 | input [31:0] wdata, 12 | output addr_ok, 13 | output data_ok, 14 | output [31:0] rdata, 15 | 16 | // AXI Interface 17 | output rd_req, 18 | output [ 2:0] rd_type, 19 | output [ 31:0] rd_addr, 20 | input rd_rdy, 21 | input ret_valid, 22 | input ret_last, 23 | input [ 31:0] ret_data, 24 | output wr_req, 25 | output [ 2:0] wr_type, 26 | output [ 31:0] wr_addr, 27 | output [ 3:0] wr_wstrb, 28 | output [127:0] wr_data, 29 | input wr_rdy 30 | ); 31 | 32 | /*-------------------- MAIN FSM --------------------*/ 33 | 34 | localparam MAIN_IDLE = 5'b00001; 35 | localparam MAIN_LOOKUP = 5'b00010; 36 | localparam MAIN_MISS = 5'b00100; 37 | localparam MAIN_REPLACE = 5'b01000; 38 | localparam MAIN_REFILL = 5'b10000; 39 | 40 | reg [4:0] main_state; 41 | reg [4:0] main_next_state; 42 | 43 | wire main_idle = main_state == MAIN_IDLE; 44 | wire main_lookup = main_state == MAIN_LOOKUP; 45 | wire main_miss = main_state == MAIN_MISS; 46 | wire main_replace = main_state == MAIN_REPLACE; 47 | wire main_refill = main_state == MAIN_REFILL; 48 | 49 | /*-------------------- WRITE BUFFER FSM --------------------*/ 50 | 51 | localparam WRITE_BUFFER_IDLE = 2'b01; 52 | localparam WRITE_BUFFER_WRITE = 2'b10; 53 | 54 | reg [1:0] write_buffer_state; 55 | reg [1:0] write_buffer_next_state; 56 | 57 | wire write_idle = write_buffer_state == WRITE_BUFFER_IDLE; 58 | wire write_write = write_buffer_state == WRITE_BUFFER_WRITE; 59 | /*-------------------- Dirty Bit Table --------------------*/ 60 | reg [255:0] D_way0; 61 | reg [255:0] D_way1; 62 | 63 | wire [7:0] dirty_index; 64 | 65 | /*-------------------- Cache RAM Interface --------------------*/ 66 | 67 | wire [ 7:0] tagv_way0_addr; 68 | wire [20:0] tagv_way0_wdata; 69 | wire [20:0] tagv_way0_rdata; 70 | wire tagv_way0_wen; 71 | wire [ 7:0] tagv_way1_addr; 72 | wire [20:0] tagv_way1_wdata; 73 | wire [20:0] tagv_way1_rdata; 74 | wire tagv_way1_wen; 75 | 76 | wire [ 7:0] bank0_way0_addr; 77 | wire [31:0] bank0_way0_wdata; 78 | wire [31:0] bank0_way0_rdata; 79 | wire [ 3:0] bank0_way0_wen; 80 | wire [ 7:0] bank1_way0_addr; 81 | wire [31:0] bank1_way0_wdata; 82 | wire [31:0] bank1_way0_rdata; 83 | wire [ 3:0] bank1_way0_wen; 84 | wire [ 7:0] bank2_way0_addr; 85 | wire [31:0] bank2_way0_wdata; 86 | wire [31:0] bank2_way0_rdata; 87 | wire [ 3:0] bank2_way0_wen; 88 | wire [ 7:0] bank3_way0_addr; 89 | wire [31:0] bank3_way0_wdata; 90 | wire [31:0] bank3_way0_rdata; 91 | wire [ 3:0] bank3_way0_wen; 92 | 93 | wire [ 7:0] bank0_way1_addr; 94 | wire [31:0] bank0_way1_wdata; 95 | wire [31:0] bank0_way1_rdata; 96 | wire [ 3:0] bank0_way1_wen; 97 | wire [ 7:0] bank1_way1_addr; 98 | wire [31:0] bank1_way1_wdata; 99 | wire [31:0] bank1_way1_rdata; 100 | wire [ 3:0] bank1_way1_wen; 101 | wire [ 7:0] bank2_way1_addr; 102 | wire [31:0] bank2_way1_wdata; 103 | wire [31:0] bank2_way1_rdata; 104 | wire [ 3:0] bank2_way1_wen; 105 | wire [ 7:0] bank3_way1_addr; 106 | wire [31:0] bank3_way1_wdata; 107 | wire [31:0] bank3_way1_rdata; 108 | wire [ 3:0] bank3_way1_wen; 109 | 110 | TAGV_RAM tagv_way0( 111 | .addra(tagv_way0_addr), 112 | .clka(clk_g), 113 | .dina(tagv_way0_wdata), 114 | .douta(tagv_way0_rdata), 115 | .wea(tagv_way0_wen) 116 | ); 117 | TAGV_RAM tagv_way1( 118 | .addra(tagv_way1_addr), 119 | .clka(clk_g), 120 | .dina(tagv_way1_wdata), 121 | .douta(tagv_way1_rdata), 122 | .wea(tagv_way1_wen) 123 | ); 124 | BANK_RAM bank0_way0( 125 | .addra(bank0_way0_addr), 126 | .clka(clk_g), 127 | .dina(bank0_way0_wdata), 128 | .douta(bank0_way0_rdata), 129 | .wea(bank0_way0_wen) 130 | ); 131 | BANK_RAM bank1_way0( 132 | .addra(bank1_way0_addr), 133 | .clka(clk_g), 134 | .dina(bank1_way0_wdata), 135 | .douta(bank1_way0_rdata), 136 | .wea(bank1_way0_wen) 137 | ); 138 | BANK_RAM bank2_way0( 139 | .addra(bank2_way0_addr), 140 | .clka(clk_g), 141 | .dina(bank2_way0_wdata), 142 | .douta(bank2_way0_rdata), 143 | .wea(bank2_way0_wen) 144 | ); 145 | BANK_RAM bank3_way0( 146 | .addra(bank3_way0_addr), 147 | .clka(clk_g), 148 | .dina(bank3_way0_wdata), 149 | .douta(bank3_way0_rdata), 150 | .wea(bank3_way0_wen) 151 | ); 152 | BANK_RAM bank0_way1( 153 | .addra(bank0_way1_addr), 154 | .clka(clk_g), 155 | .dina(bank0_way1_wdata), 156 | .douta(bank0_way1_rdata), 157 | .wea(bank0_way1_wen) 158 | ); 159 | BANK_RAM bank1_way1( 160 | .addra(bank1_way1_addr), 161 | .clka(clk_g), 162 | .dina(bank1_way1_wdata), 163 | .douta(bank1_way1_rdata), 164 | .wea(bank1_way1_wen) 165 | ); 166 | BANK_RAM bank2_way1( 167 | .addra(bank2_way1_addr), 168 | .clka(clk_g), 169 | .dina(bank2_way1_wdata), 170 | .douta(bank2_way1_rdata), 171 | .wea(bank2_way1_wen) 172 | ); 173 | BANK_RAM bank3_way1( 174 | .addra(bank3_way1_addr), 175 | .clka(clk_g), 176 | .dina(bank3_way1_wdata), 177 | .douta(bank3_way1_rdata), 178 | .wea(bank3_way1_wen) 179 | ); 180 | 181 | /*-------------------- Bank Selection --------------------*/ 182 | wire wr_bank0_hit; 183 | wire wr_bank1_hit; 184 | wire wr_bank2_hit; 185 | wire wr_bank3_hit; 186 | 187 | 188 | /*-------------------- Request Buffer --------------------*/ 189 | 190 | reg rq_op_r; 191 | reg [ 7:0] rq_index_r; 192 | reg [19:0] rq_tag_r; 193 | reg [ 3:0] rq_offset_r; 194 | reg [ 3:0] rq_wstrb_r; 195 | reg [31:0] rq_wdata_r; 196 | 197 | /*-------------------- Write Buffer --------------------*/ 198 | reg wr_way_r; 199 | reg [19:0] wr_tag_r; 200 | reg [ 1:0] wr_bank_r; 201 | reg [ 7:0] wr_index_r; 202 | reg [ 3:0] wr_wstrb_r; 203 | reg [31:0] wr_wdata_r; 204 | reg [ 3:0] wr_offset_r; 205 | 206 | /*-------------------- Tag Compare --------------------*/ 207 | 208 | wire hit_way; 209 | wire way0_hit; 210 | wire way1_hit; 211 | 212 | wire wr_way0_hit; 213 | wire wr_way1_hit; 214 | 215 | wire cache_hit; 216 | 217 | 218 | /*-------------------- Data Select --------------------*/ 219 | 220 | wire [ 31:0] way0_load_word; 221 | wire [ 31:0] way1_load_word; 222 | wire [ 31:0] load_res; 223 | wire [127:0] replace_data; 224 | wire [ 19:0] replace_tag; 225 | reg [127:0] replace_data_r; 226 | reg [ 19:0] replace_tag_r; 227 | wire replace_way; 228 | 229 | /*-------------------- Miss Buffer --------------------*/ 230 | 231 | reg rq_replace_way_r; 232 | reg [1:0] num_ret_data; 233 | // Generate a pseudo random number to choose **replaced way** 234 | assign replace_way = rq_replace_way_r; 235 | 236 | /*-------------------- LFSR --------------------*/ 237 | reg [22:0] pseudo_random_23; 238 | 239 | /*-------------------- Cache rdata --------------------*/ 240 | wire way0_v; 241 | wire way1_v; 242 | wire [ 19:0] way0_tag; 243 | wire [ 19:0] way1_tag; 244 | wire [127:0] way0_data; 245 | wire [127:0] way1_data; 246 | 247 | assign way0_v = tagv_way0_rdata[0]; 248 | assign way1_v = tagv_way1_rdata[0]; 249 | assign way0_tag = tagv_way0_rdata[20:1]; 250 | assign way1_tag = tagv_way1_rdata[20:1]; 251 | assign way0_data= {bank3_way0_rdata, bank2_way0_rdata, 252 | bank1_way0_rdata, bank0_way0_rdata 253 | }; 254 | assign way1_data= {bank3_way1_rdata, bank2_way1_rdata, 255 | bank1_way1_rdata, bank0_way1_rdata 256 | }; 257 | 258 | /*-------------------- Tag Compare --------------------*/ 259 | assign way0_hit = way0_v && (way0_tag == rq_tag_r); 260 | assign way1_hit = way1_v && (way1_tag == rq_tag_r); 261 | 262 | assign wr_way0_hit = way0_v && (way0_tag == wr_tag_r); 263 | assign wr_way1_hit = way1_v && (way1_tag == wr_tag_r); 264 | assign hit_way = way1_hit; 265 | assign cache_hit = way0_hit || way1_hit; 266 | 267 | /*-------------------- MAIN FSM --------------------*/ 268 | 269 | always @(posedge clk_g) begin 270 | if(~resetn) begin 271 | main_state <= MAIN_IDLE; 272 | end 273 | else begin 274 | main_state <= main_next_state; 275 | end 276 | end 277 | 278 | always @(*) begin 279 | case (main_state) 280 | MAIN_IDLE: begin 281 | if(valid) begin 282 | main_next_state = MAIN_LOOKUP; 283 | end 284 | else begin 285 | main_next_state = MAIN_IDLE; 286 | end 287 | end 288 | MAIN_LOOKUP: begin 289 | if (cache_hit && ~valid) begin 290 | main_next_state = MAIN_IDLE; 291 | end 292 | else if (cache_hit && valid) begin 293 | main_next_state = MAIN_LOOKUP; 294 | end 295 | else begin 296 | main_next_state = MAIN_MISS; 297 | end 298 | end 299 | MAIN_MISS: begin 300 | if(wr_rdy) begin 301 | main_next_state = MAIN_REPLACE; 302 | end 303 | else begin 304 | main_next_state = MAIN_MISS; 305 | end 306 | end 307 | MAIN_REPLACE: begin 308 | if(rd_rdy) begin 309 | main_next_state = MAIN_REFILL; 310 | end 311 | else begin 312 | main_next_state = MAIN_REPLACE; 313 | end 314 | end 315 | MAIN_REFILL: begin 316 | if(ret_valid && ret_last) begin 317 | main_next_state = MAIN_IDLE; 318 | end 319 | else begin 320 | main_next_state = MAIN_REFILL; 321 | end 322 | end 323 | default: 324 | main_next_state = MAIN_IDLE; 325 | endcase 326 | end 327 | 328 | 329 | 330 | /*-------------------- WRITE BUFFER FSM --------------------*/ 331 | wire hit_write = main_lookup && cache_hit && rq_op_r; 332 | 333 | always @(posedge clk_g) begin 334 | if(~resetn) begin 335 | write_buffer_state <= WRITE_BUFFER_IDLE; 336 | end 337 | else begin 338 | write_buffer_state <= write_buffer_next_state; 339 | end 340 | end 341 | 342 | always @(*) begin 343 | case (write_buffer_state) 344 | WRITE_BUFFER_IDLE: begin 345 | if(main_lookup && hit_write) begin 346 | write_buffer_next_state = WRITE_BUFFER_WRITE; 347 | end 348 | else begin 349 | write_buffer_next_state = WRITE_BUFFER_IDLE; 350 | end 351 | end 352 | WRITE_BUFFER_WRITE: begin 353 | if(~hit_write) begin 354 | write_buffer_next_state = WRITE_BUFFER_IDLE; 355 | end 356 | else begin 357 | write_buffer_next_state = WRITE_BUFFER_WRITE; 358 | end 359 | end 360 | endcase 361 | end 362 | 363 | /*-------------------- NOT IDLE STATE --------------------*/ 364 | reg not_idle; 365 | 366 | always @(posedge clk_g) begin 367 | if (~resetn) begin 368 | not_idle <= 1'b0; 369 | end 370 | else if (not_idle && data_ok) begin 371 | not_idle <= 1'b0; 372 | end 373 | else if (main_idle && valid) begin 374 | not_idle <= 1'b1; 375 | end 376 | end 377 | 378 | /*-------------------- Bank Selection --------------------*/ 379 | 380 | assign wr_bank0_hit = wr_offset_r[3:2] == 2'b00; 381 | assign wr_bank1_hit = wr_offset_r[3:2] == 2'b01; 382 | assign wr_bank2_hit = wr_offset_r[3:2] == 2'b10; 383 | assign wr_bank3_hit = wr_offset_r[3:2] == 2'b11; 384 | 385 | /*-------------------- Dirty Bit Table --------------------*/ 386 | 387 | assign dirty_index = not_idle ? rq_index_r : 388 | valid ? index : 389 | 8'b0; 390 | 391 | always @ (posedge clk_g) begin 392 | if(!resetn) begin 393 | D_way0 <= 256'b0; 394 | D_way1 <= 256'b0; 395 | end 396 | else if(main_lookup && rq_op_r)begin 397 | if(way0_hit) 398 | D_way0[dirty_index] <= 1'b1; 399 | else if(way1_hit) 400 | D_way1[dirty_index] <= 1'b1; 401 | end 402 | else if(main_refill)begin 403 | if(replace_way == 0) 404 | D_way0[dirty_index] <= rq_op_r; 405 | else 406 | D_way1[dirty_index] <= rq_op_r; 407 | end 408 | end 409 | 410 | /*-------------------- Request Buffer --------------------*/ 411 | always @(posedge clk_g) begin 412 | if (~resetn) begin 413 | rq_op_r <= 1'b0; 414 | rq_index_r <= 8'b0; 415 | rq_tag_r <= 20'b0; 416 | rq_offset_r <= 4'b0; 417 | rq_wstrb_r <= 4'b0; 418 | rq_wdata_r <= 32'b0; 419 | end 420 | else if (main_idle && main_next_state == MAIN_LOOKUP || 421 | main_lookup && main_next_state == MAIN_LOOKUP) begin //only in these conditions, request can be accepted 422 | rq_op_r <= op; 423 | rq_index_r <= index; 424 | rq_tag_r <= tag; 425 | rq_offset_r <= offset; 426 | rq_wstrb_r <= wstrb; 427 | rq_wdata_r <= wdata; 428 | rq_replace_way_r <= pseudo_random_23[0]; 429 | end 430 | end 431 | 432 | /*-------------------- LFSR --------------------*/ 433 | always @ (posedge clk_g) begin 434 | if (~resetn) 435 | pseudo_random_23 <= {7'b1010101,16'h00FF}; 436 | else 437 | pseudo_random_23 <= {pseudo_random_23[21:0], pseudo_random_23[22] ^ pseudo_random_23[17]}; 438 | end 439 | 440 | /*-------------------- Miss Buffer --------------------*/ 441 | always @(posedge clk_g) begin 442 | if (!resetn) 443 | num_ret_data <= 2'b00; 444 | else if (ret_last && ret_valid) 445 | num_ret_data <= 2'b00; 446 | else if (ret_valid) 447 | num_ret_data <= num_ret_data + 1'b1; 448 | end 449 | 450 | /*-------------------- Data Select --------------------*/ 451 | assign way0_load_word = way0_data[rq_offset_r[3:2]*32 +: 32]; 452 | assign way1_load_word = way1_data[rq_offset_r[3:2]*32 +: 32]; 453 | assign load_res = {32{way0_hit}} & way0_load_word | 454 | {32{way1_hit}} & way1_load_word; 455 | 456 | assign replace_data = replace_way ? way1_data : way0_data; 457 | assign replace_tag = replace_way ? way1_tag : way0_tag; 458 | 459 | always @(posedge clk_g) begin 460 | if (main_lookup & main_next_state == MAIN_MISS) begin 461 | replace_tag_r <= replace_tag; 462 | replace_data_r <= replace_data;//!!not used, write buffer not yet finished now 463 | end 464 | end 465 | 466 | /*-------------------- Write Buffer --------------------*/ 467 | always @(posedge clk_g) begin 468 | if (main_lookup && hit_write) begin 469 | wr_tag_r <= rq_tag_r; 470 | wr_way_r <= hit_way; 471 | wr_bank_r <= rq_offset_r[3:2]; 472 | wr_index_r <= rq_index_r; 473 | wr_wstrb_r <= rq_wstrb_r; 474 | wr_wdata_r <= rq_wdata_r; 475 | wr_offset_r <= rq_offset_r; 476 | end 477 | end 478 | 479 | /*-------------------- CPU Interface --------------------*/ 480 | 481 | assign rdata = main_lookup ? load_res : 482 | main_refill && ret_valid ? rq_wdata_r : 483 | 32'b0; 484 | assign addr_ok = main_idle && main_next_state == MAIN_LOOKUP || 485 | main_lookup && main_next_state == MAIN_LOOKUP; 486 | assign data_ok = main_lookup && main_next_state == MAIN_IDLE || 487 | main_lookup && main_next_state == MAIN_LOOKUP || 488 | main_refill && ret_valid && num_ret_data == rq_offset_r[3:2]; 489 | 490 | /*-------------------- AXI Interface --------------------*/ 491 | 492 | assign rd_req = main_replace; 493 | assign rd_type = 3'b100; 494 | assign rd_addr = {rq_tag_r, rq_index_r, 4'b0000}; 495 | 496 | reg wr_req_r; 497 | 498 | // Replaced Cache block is dirty 499 | // It's real *natural* language programming LOL 500 | wire replaced_cache_is_dirty = D_way0[dirty_index] && ~replace_way || 501 | D_way1[dirty_index] && replace_way; 502 | 503 | always @(posedge clk_g) begin 504 | if (~resetn) begin 505 | wr_req_r <= 1'b0; 506 | end 507 | else if (main_miss && replaced_cache_is_dirty && wr_req_r == 1'b0) begin 508 | wr_req_r <= 1'b1; 509 | end 510 | else if (wr_rdy && wr_req) 511 | wr_req_r <= 1'b0; 512 | end 513 | 514 | assign wr_req = wr_req_r; 515 | assign wr_type = 3'b100; 516 | assign wr_addr = {replace_tag_r, rq_index_r, 4'b0000}; 517 | assign wr_data = replace_data; 518 | assign wr_wstrb = 4'hf; 519 | 520 | assign tagv_way0_addr = write_write ? wr_index_r : 521 | main_next_state == MAIN_LOOKUP ? index : rq_index_r; 522 | /*not_idle ? rq_index_r : 523 | valid ? index : 524 | 8'b0;*///??? 525 | assign tagv_way1_addr = tagv_way0_addr; 526 | assign tagv_way0_wen = main_refill && ~replace_way || write_write && ~wr_way_r; 527 | assign tagv_way1_wen = main_refill && replace_way || write_write && wr_way_r; 528 | assign tagv_way0_wdata = write_write ? {way0_tag, 1'b1} : {rq_tag_r, 1'b1}; 529 | assign tagv_way1_wdata = write_write ? {way1_tag, 1'b1} : {rq_tag_r, 1'b1}; 530 | 531 | assign bank0_way0_addr = write_write ? wr_index_r : 532 | main_next_state == MAIN_LOOKUP ? index : 533 | rq_index_r; 534 | assign bank1_way0_addr = bank0_way0_addr; 535 | assign bank2_way0_addr = bank0_way0_addr; 536 | assign bank3_way0_addr = bank0_way0_addr; 537 | assign bank0_way1_addr = bank0_way0_addr; 538 | assign bank1_way1_addr = bank0_way0_addr; 539 | assign bank2_way1_addr = bank0_way0_addr; 540 | assign bank3_way1_addr = bank0_way0_addr; 541 | 542 | assign bank0_way0_wen = (write_write && wr_way0_hit && wr_bank0_hit) ? wr_wstrb_r : 543 | (main_refill && num_ret_data == 2'b00 && ret_valid && ~replace_way) ? 4'hf : 4'h0; 544 | assign bank1_way0_wen = (write_write && wr_way0_hit && wr_bank1_hit) ? wr_wstrb_r : 545 | (main_refill && num_ret_data == 2'b01 && ret_valid && ~replace_way) ? 4'hf : 4'h0; 546 | assign bank2_way0_wen = (write_write && wr_way0_hit && wr_bank2_hit) ? wr_wstrb_r : 547 | (main_refill && num_ret_data == 2'b10 && ret_valid && ~replace_way) ? 4'hf : 4'h0; 548 | assign bank3_way0_wen = (write_write && wr_way0_hit && wr_bank3_hit) ? wr_wstrb_r : 549 | (main_refill && num_ret_data == 2'b11 && ret_valid && ~replace_way) ? 4'hf : 4'h0; 550 | assign bank0_way1_wen = (write_write && wr_way1_hit && wr_bank0_hit) ? wr_wstrb_r : 551 | (main_refill && num_ret_data == 2'b00 && ret_valid && replace_way) ? 4'hf : 4'h0; 552 | assign bank1_way1_wen = (write_write && wr_way1_hit && wr_bank1_hit) ? wr_wstrb_r : 553 | (main_refill && num_ret_data == 2'b01 && ret_valid && replace_way) ? 4'hf : 4'h0; 554 | assign bank2_way1_wen = (write_write && wr_way1_hit && wr_bank2_hit) ? wr_wstrb_r : 555 | (main_refill && num_ret_data == 2'b10 && ret_valid && replace_way) ? 4'hf : 4'h0; 556 | assign bank3_way1_wen = (write_write && wr_way1_hit && wr_bank3_hit) ? wr_wstrb_r : 557 | (main_refill && num_ret_data == 2'b11 && ret_valid && replace_way) ? 4'hf : 4'h0; 558 | 559 | wire [31:0] refill_data = {32{rq_wstrb_r == 4'b0000}} & ret_data | 560 | {32{rq_wstrb_r == 4'b0001}} & {ret_data[31:8], rq_wdata_r[7:0]} | 561 | {32{rq_wstrb_r == 4'b0011}} & {ret_data[31:16], rq_wdata_r[15:0]} | 562 | {32{rq_wstrb_r == 4'b0111}} & {ret_data[31:24], rq_wdata_r[23:0]} | 563 | {32{rq_wstrb_r == 4'b1111}} & rq_wdata_r | 564 | {32{rq_wstrb_r == 4'b1110}} & {rq_wdata_r[31:8], ret_data[7:0]} | 565 | {32{rq_wstrb_r == 4'b1100}} & {rq_wdata_r[31:16], ret_data[15:0]} | 566 | {32{rq_wstrb_r == 4'b1000}} & {rq_wdata_r[31:24], ret_data[23:0]}; 567 | 568 | assign bank0_way0_wdata = write_write && ~wr_way_r ? wr_wdata_r : 569 | main_refill ? (rq_offset_r[3:2] == 2'b00) ? refill_data : ret_data : 32'b0; 570 | assign bank1_way0_wdata = write_write && ~wr_way_r ? wr_wdata_r : 571 | main_refill ? (rq_offset_r[3:2] == 2'b01) ? refill_data : ret_data : 32'b0; 572 | assign bank2_way0_wdata = write_write && ~wr_way_r ? wr_wdata_r : 573 | main_refill ? (rq_offset_r[3:2] == 2'b10) ? refill_data : ret_data : 32'b0; 574 | assign bank3_way0_wdata = write_write && ~wr_way_r ? wr_wdata_r : 575 | main_refill ? (rq_offset_r[3:2] == 2'b11) ? refill_data : ret_data : 32'b0; 576 | assign bank0_way1_wdata = write_write && wr_way_r ? wr_wdata_r : 577 | main_refill ? (rq_offset_r[3:2] == 2'b00) ? refill_data : ret_data : 32'b0; 578 | assign bank1_way1_wdata = write_write && wr_way_r ? wr_wdata_r : 579 | main_refill ? (rq_offset_r[3:2] == 2'b01) ? refill_data : ret_data : 32'b0; 580 | assign bank2_way1_wdata = write_write && wr_way_r ? wr_wdata_r : 581 | main_refill ? (rq_offset_r[3:2] == 2'b10) ? refill_data : ret_data : 32'b0; 582 | assign bank3_way1_wdata = write_write && wr_way_r ? wr_wdata_r : 583 | main_refill ? (rq_offset_r[3:2] == 2'b11) ? refill_data : ret_data : 32'b0; 584 | endmodule -------------------------------------------------------------------------------- /cpu_core.v: -------------------------------------------------------------------------------- 1 | `include "mycpu.h" 2 | module cpu_core 3 | #( 4 | parameter TLBNUM = 16 5 | ) 6 | ( 7 | input clk, 8 | input resetn, 9 | // inst sram interface 10 | output inst_sram_req, 11 | output [ 3:0] inst_sram_wstrb, 12 | output [31:0] inst_sram_addr, 13 | output [31:0] inst_sram_wdata, 14 | input [31:0] inst_sram_rdata, 15 | output [ 1:0] inst_sram_size, 16 | input inst_sram_addr_ok, 17 | input inst_sram_data_ok, 18 | output inst_sram_wr, 19 | // data sram interface 20 | output data_sram_req, 21 | output [ 3:0] data_sram_wstrb, 22 | output [31:0] data_sram_addr, 23 | output [31:0] data_sram_wdata, 24 | input [31:0] data_sram_rdata, 25 | output [ 1:0] data_sram_size, 26 | input data_sram_addr_ok, 27 | input data_sram_data_ok, 28 | output data_sram_wr, 29 | // trace debug interface 30 | output [31:0] debug_wb_pc, 31 | output [ 3:0] debug_wb_rf_wen, 32 | output [ 4:0] debug_wb_rf_wnum, 33 | output [31:0] debug_wb_rf_wdata 34 | ); 35 | 36 | reg reset; 37 | always @(posedge clk) reset <= ~resetn; 38 | 39 | wire ds_allowin; 40 | wire es_allowin; 41 | wire ms_allowin; 42 | wire ws_allowin; 43 | wire fs_to_ds_valid; 44 | wire ds_to_es_valid; 45 | wire es_to_ms_valid; 46 | wire ms_to_ws_valid; 47 | wire [`FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus; 48 | wire [`DS_TO_ES_BUS_WD -1:0] ds_to_es_bus; 49 | wire [`ES_TO_MS_BUS_WD -1:0] es_to_ms_bus; 50 | wire [`MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus; 51 | wire [`WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus; 52 | wire [`WS_TO_ES_BUS_WD -1:0] ws_to_es_bus; 53 | wire [`BR_BUS_WD -1:0] br_bus; 54 | wire [`ES_FORWARD_WD -1:0] es_forward; 55 | wire [`MS_FORWARD_WD -1:0] ms_forward; 56 | wire [`WS_FORWARD_WD -1:0] ws_forward; 57 | //wire es_valid; 58 | wire final_ex; 59 | wire [`WS_TO_FS_BUS_WD -1:0] ws_to_fs_bus; 60 | wire back_ertn_flush; 61 | wire back_ex; 62 | wire [63 :0] counter; 63 | wire ms_ertn_flush; 64 | wire ms_to_es_valid; 65 | wire ms_to_es_ex; 66 | wire es_ex_detected_to_fs; 67 | wire ms_ex_detected; 68 | // tlb 69 | wire [ 18:0] s0_vppn; 70 | wire s0_va_bit12; 71 | wire [ 9:0] s0_asid; 72 | wire s0_found; 73 | wire [$clog2(TLBNUM)-1:0] s0_index; 74 | wire [ 19:0] s0_ppn; 75 | wire [ 5:0] s0_ps; 76 | wire [ 1:0] s0_plv; 77 | wire [ 1:0] s0_mat; 78 | wire s0_d; 79 | wire s0_v; 80 | wire [ 18:0] s1_vppn; 81 | wire s1_va_bit12; 82 | wire [ 9:0] s1_asid; 83 | wire s1_found; 84 | wire [$clog2(TLBNUM)-1:0] s1_index; 85 | wire [ 19:0] s1_ppn; 86 | wire [ 5:0] s1_ps; 87 | wire [ 1:0] s1_plv; 88 | wire [ 1:0] s1_mat; 89 | wire s1_d; 90 | wire s1_v; 91 | wire [ 4:0] invtlb_op; 92 | wire inst_invtlb; 93 | wire we; 94 | wire [$clog2(TLBNUM)-1:0] w_index; 95 | wire w_e; 96 | wire [ 5:0] w_ps; 97 | wire [ 18:0] w_vppn; 98 | wire [ 9:0] w_asid; 99 | wire w_g; 100 | wire [ 19:0] w_ppn0; 101 | wire [ 1:0] w_plv0; 102 | wire [ 1:0] w_mat0; 103 | wire w_d0; 104 | wire w_v0; 105 | wire [ 19:0] w_ppn1; 106 | wire [ 1:0] w_plv1; 107 | wire [ 1:0] w_mat1; 108 | wire w_d1; 109 | wire w_v1; 110 | wire [$clog2(TLBNUM)-1:0] r_index; 111 | wire r_e; 112 | wire [ 18:0] r_vppn; 113 | wire [ 5:0] r_ps; 114 | wire [ 9:0] r_asid; 115 | wire r_g; 116 | wire [ 19:0] r_ppn0; 117 | wire [ 1:0] r_plv0; 118 | wire [ 1:0] r_mat0; 119 | wire r_d0; 120 | wire r_v0; 121 | wire [ 19:0] r_ppn1; 122 | wire [ 1:0] r_plv1; 123 | wire [ 1:0] r_mat1; 124 | wire r_d1; 125 | wire r_v1; 126 | wire inst_tlbsrch; 127 | wire inst_tlbrd; 128 | wire inst_tlbfill; 129 | wire inst_tlbwr; 130 | wire [ 97:0] csr_tlb_in; 131 | wire [ 97:0] csr_tlb_out; 132 | assign csr_tlb_in = {//es_valid, //96 133 | inst_tlbwr, //97 134 | inst_tlbfill,//96 135 | inst_tlbsrch,//95 136 | inst_tlbrd, //94 137 | s1_found, //93 138 | s1_index, //92:89 139 | r_e, //88 140 | r_vppn, //87:69 141 | r_ps, //68:63 142 | r_asid, //62:53 143 | r_g, //52 144 | r_ppn0, //51:32 145 | r_plv0, //31:30 146 | r_mat0, //29:28 147 | r_d0, //27 148 | r_v0, //26 149 | r_ppn1, //25:6 150 | r_plv1, //5:4 151 | r_mat1, //3:2 152 | r_d1, //1 153 | r_v1 //0 154 | }; 155 | assign {we, //97 156 | w_index,//96:93 157 | w_e, //92 158 | w_vppn, //91:73 159 | w_ps, //72:67 160 | w_asid, //66:57 161 | w_g, //56 162 | w_ppn0, //55:36 163 | w_plv0, //35:34 164 | w_mat0, //33:32 165 | w_d0, //31 166 | w_v0, //30 167 | w_ppn1, //29:10 168 | w_plv1, //9:8 169 | w_mat1, //7:6 170 | w_d1, //5 171 | w_v1, //4 172 | r_index //3:0 173 | } = csr_tlb_out; 174 | 175 | // IF stage 176 | if_stage if_stage( 177 | .clk (clk ), 178 | .reset (reset ), 179 | //allowin 180 | .ds_allowin (ds_allowin ), 181 | //brbus 182 | .br_bus (br_bus ), 183 | //outputs 184 | .fs_to_ds_valid (fs_to_ds_valid ), 185 | .fs_to_ds_bus (fs_to_ds_bus ), 186 | // inst sram interface 187 | .inst_sram_req (inst_sram_req ), 188 | .inst_sram_wstrb (inst_sram_wstrb ), 189 | .inst_sram_addr (inst_sram_addr ), 190 | .inst_sram_wdata(inst_sram_wdata), 191 | .inst_sram_rdata(inst_sram_rdata), 192 | .ws_to_fs_bus (ws_to_fs_bus ), 193 | .es_forward (es_forward ), 194 | .ms_forward (ms_forward ), 195 | .ws_forward (ws_forward ), 196 | .back_ertn_flush(back_ertn_flush), 197 | .back_ex (back_ex ), 198 | .inst_sram_size (inst_sram_size ), 199 | .inst_sram_addr_ok(inst_sram_addr_ok), 200 | .inst_sram_data_ok(inst_sram_data_ok), 201 | .inst_sram_wr (inst_sram_wr ), 202 | .es_ex_detected_to_fs(es_ex_detected_to_fs), 203 | .ms_ex_detected (ms_ex_detected ), 204 | // search port 0 (for fetch) 205 | .s0_vppn (s0_vppn ), 206 | .s0_va_bit12 (s0_va_bit12 ), 207 | .s0_asid (s0_asid ), 208 | .s0_found (s0_found ), 209 | .s0_index (s0_index ), 210 | .s0_ppn (s0_ppn ), 211 | .s0_ps (s0_ps ), 212 | .s0_plv (s0_plv ), 213 | .s0_mat (s0_mat ), 214 | .s0_d (s0_d ), 215 | .s0_v (s0_v ) 216 | ); 217 | // ID stage 218 | id_stage id_stage( 219 | .clk (clk ), 220 | .reset (reset ), 221 | //allowin 222 | .es_allowin (es_allowin ), 223 | .ds_allowin (ds_allowin ), 224 | //from fs 225 | .fs_to_ds_valid (fs_to_ds_valid ), 226 | .fs_to_ds_bus (fs_to_ds_bus ), 227 | //to es 228 | .ds_to_es_valid (ds_to_es_valid ), 229 | .ds_to_es_bus (ds_to_es_bus ), 230 | //to fs 231 | .br_bus (br_bus ), 232 | 233 | //to rf: for write back 234 | .ws_to_rf_bus (ws_to_rf_bus ), 235 | .es_forward (es_forward ), 236 | .ms_forward (ms_forward ), 237 | .ws_forward (ws_forward ), 238 | .back_ertn_flush(back_ertn_flush), 239 | .back_ex (back_ex ) 240 | ); 241 | // EXE stage 242 | exe_stage exe_stage( 243 | .clk (clk ), 244 | .reset (reset ), 245 | .final_ex (final_ex ), 246 | //allowin 247 | .ms_allowin (ms_allowin ), 248 | .es_allowin (es_allowin ), 249 | // .es_valid (es_valid ), 250 | //from ds 251 | .ds_to_es_valid (ds_to_es_valid ), 252 | .ds_to_es_bus (ds_to_es_bus ), 253 | //to ms 254 | .es_to_ms_valid (es_to_ms_valid ), 255 | .es_to_ms_bus (es_to_ms_bus ), 256 | // data sram interface 257 | .data_sram_req (data_sram_req ), 258 | .data_sram_wstrb(data_sram_wstrb ), 259 | .data_sram_addr (data_sram_addr ), 260 | .data_sram_wdata(data_sram_wdata), 261 | .es_forward (es_forward ), 262 | .ms_ertn_flush (ms_ertn_flush ), 263 | .ms_to_es_valid (ms_to_es_valid ), 264 | // counter from ws 265 | .es_counter (counter ), 266 | .back_ertn_flush(back_ertn_flush), 267 | .back_ex (back_ex ), 268 | .data_sram_size (data_sram_size ), 269 | .data_sram_addr_ok(data_sram_addr_ok), 270 | .data_sram_wr (data_sram_wr ), 271 | .ms_to_es_ex (ms_to_es_ex ), 272 | .es_ex_detected_to_fs(es_ex_detected_to_fs), 273 | // search port 1 (for load/store) 274 | .s1_vppn (s1_vppn ), 275 | .s1_va_bit12 (s1_va_bit12 ), 276 | .s1_asid (s1_asid ), 277 | .s1_found (s1_found ), 278 | // .s1_index (s1_index ), 279 | .s1_ppn (s1_ppn ), 280 | .s1_ps (s1_ps ), 281 | .s1_plv (s1_plv ), 282 | .s1_mat (s1_mat ), 283 | .s1_d (s1_d ), 284 | .s1_v (s1_v ), 285 | // invtlb opcode 286 | .invtlb_op (invtlb_op ), 287 | .inst_tlbsrch (inst_tlbsrch ), 288 | .inst_tlbrd (inst_tlbrd ), 289 | .inst_tlbwr (inst_tlbwr ), 290 | .inst_tlbfill (inst_tlbfill ), 291 | .inst_invtlb (inst_invtlb ), 292 | .ws_to_es_bus (ws_to_es_bus ) 293 | ); 294 | // MEM stage 295 | mem_stage mem_stage( 296 | .clk (clk ), 297 | .reset (reset ), 298 | .final_ex (final_ex ), 299 | //allowin 300 | .ws_allowin (ws_allowin ), 301 | .ms_allowin (ms_allowin ), 302 | //from es 303 | .es_to_ms_valid (es_to_ms_valid ), 304 | .es_to_ms_bus (es_to_ms_bus ), 305 | //to ws 306 | .ms_to_ws_valid (ms_to_ws_valid ), 307 | .ms_to_ws_bus (ms_to_ws_bus ), 308 | //from data-sram 309 | .data_sram_rdata(data_sram_rdata), 310 | .data_sram_data_ok(data_sram_data_ok), 311 | .ms_forward (ms_forward ), 312 | .back_ertn_flush(back_ertn_flush), 313 | .ms_ertn_flush (ms_ertn_flush ), 314 | .ms_to_es_valid (ms_to_es_valid ), 315 | .back_ex (back_ex ), 316 | .ms_to_es_ex (ms_to_es_ex ), 317 | .ms_ex_detected (ms_ex_detected ) 318 | ); 319 | // WB stage 320 | wb_stage wb_stage( 321 | .clk (clk ), 322 | .reset (reset ), 323 | //allowin 324 | .ws_allowin (ws_allowin ), 325 | //from ms 326 | .ms_to_ws_valid (ms_to_ws_valid ), 327 | .ms_to_ws_bus (ms_to_ws_bus ), 328 | .final_ex (final_ex ), 329 | //to rf: for write back 330 | .ws_to_rf_bus (ws_to_rf_bus ), 331 | //trace debug interface 332 | .debug_wb_pc (debug_wb_pc ), 333 | .debug_wb_rf_wen (debug_wb_rf_wen ), 334 | .debug_wb_rf_wnum (debug_wb_rf_wnum ), 335 | .debug_wb_rf_wdata(debug_wb_rf_wdata), 336 | .ws_forward (ws_forward ), 337 | .ws_to_fs_bus (ws_to_fs_bus ), 338 | //counter 339 | .counter (counter ), 340 | .back_ertn_flush (back_ertn_flush ), 341 | .back_ex (back_ex ), 342 | // tlb 343 | .csr_tlb_out (csr_tlb_out ), 344 | .csr_tlb_in (csr_tlb_in ), 345 | .ws_to_es_bus (ws_to_es_bus ) 346 | ); 347 | // tlb 348 | tlb tlb( 349 | .clk (clk ), 350 | // search port 0 (for fetch) 351 | .s0_vppn (s0_vppn ), 352 | .s0_va_bit12 (s0_va_bit12 ), 353 | .s0_asid (s0_asid ), 354 | .s0_found (s0_found ), 355 | .s0_index (s0_index ), 356 | .s0_ppn (s0_ppn ), 357 | .s0_ps (s0_ps ), 358 | .s0_plv (s0_plv ), 359 | .s0_mat (s0_mat ), 360 | .s0_d (s0_d ), 361 | .s0_v (s0_v ), 362 | // search port 1 (for load/store) 363 | .s1_vppn (s1_vppn ), 364 | .s1_va_bit12 (s1_va_bit12 ), 365 | .s1_asid (s1_asid ), 366 | .s1_found (s1_found ), 367 | .s1_index (s1_index ), 368 | .s1_ppn (s1_ppn ), 369 | .s1_ps (s1_ps ), 370 | .s1_plv (s1_plv ), 371 | .s1_mat (s1_mat ), 372 | .s1_d (s1_d ), 373 | .s1_v (s1_v ), 374 | // invtlb opcode 375 | .invtlb_op (invtlb_op ), 376 | .inst_invtlb (inst_invtlb ), 377 | // write port 378 | .we (we ), 379 | .w_index (w_index ), 380 | .w_e (w_e ), 381 | .w_ps (w_ps ), 382 | .w_vppn (w_vppn ), 383 | .w_asid (w_asid ), 384 | .w_g (w_g ), 385 | .w_ppn0 (w_ppn0 ), 386 | .w_plv0 (w_plv0 ), 387 | .w_mat0 (w_mat0 ), 388 | .w_d0 (w_d0 ), 389 | .w_v0 (w_v0 ), 390 | .w_ppn1 (w_ppn1 ), 391 | .w_plv1 (w_plv1 ), 392 | .w_mat1 (w_mat1 ), 393 | .w_d1 (w_d1 ), 394 | .w_v1 (w_v1 ), 395 | // read port 396 | .r_index (r_index ), 397 | .r_e (r_e ), 398 | .r_vppn (r_vppn ), 399 | .r_ps (r_ps ), 400 | .r_asid (r_asid ), 401 | .r_g (r_g ), 402 | .r_ppn0 (r_ppn0 ), 403 | .r_plv0 (r_plv0 ), 404 | .r_mat0 (r_mat0 ), 405 | .r_d0 (r_d0 ), 406 | .r_v0 (r_v0 ), 407 | .r_ppn1 (r_ppn1 ), 408 | .r_plv1 (r_plv1 ), 409 | .r_mat1 (r_mat1 ), 410 | .r_d1 (r_d1 ), 411 | .r_v1 (r_v1 ) 412 | ); 413 | endmodule 414 | -------------------------------------------------------------------------------- /exe_stage.v: -------------------------------------------------------------------------------- 1 | `include "mycpu.h" 2 | 3 | module exe_stage#( 4 | parameter TLBNUM = 16 5 | ) 6 | ( 7 | input clk , 8 | input reset , 9 | input final_ex , 10 | //allowin 11 | input ms_allowin , 12 | output es_allowin , 13 | // output es_valid , 14 | //from ds 15 | input ds_to_es_valid, 16 | input [`DS_TO_ES_BUS_WD -1:0] ds_to_es_bus , 17 | //to ms 18 | output es_to_ms_valid, 19 | output [`ES_TO_MS_BUS_WD -1:0] es_to_ms_bus , 20 | // data sram interface 21 | output data_sram_req , 22 | output data_sram_wr , 23 | output [ 3:0] data_sram_wstrb, 24 | output [ 31:0] data_sram_addr , 25 | output [ 31:0] data_sram_wdata, 26 | output [ 1:0] data_sram_size , 27 | input data_sram_addr_ok, 28 | output [`ES_FORWARD_WD -1:0] es_forward , 29 | // counter 30 | input [ 63:0] es_counter , 31 | input ms_ertn_flush , 32 | input ms_to_es_valid , 33 | input back_ertn_flush, 34 | input back_ex , 35 | input ms_to_es_ex , 36 | output es_ex_detected_to_fs, 37 | // search port 1 (for load/store) 38 | output [ 18:0] s1_vppn, 39 | output s1_va_bit12, 40 | output [ 9:0] s1_asid, 41 | input s1_found, 42 | // input [$clog2(TLBNUM)-1:0] s1_index, 43 | input [ 19:0] s1_ppn, 44 | input [ 5:0] s1_ps, 45 | input [ 1:0] s1_plv, 46 | input [ 1:0] s1_mat, 47 | input s1_d, 48 | input s1_v, 49 | // invtlb opcode 50 | output [ 4:0] invtlb_op, 51 | output inst_tlbsrch, 52 | output inst_tlbrd, 53 | output inst_tlbwr, 54 | output inst_tlbfill, 55 | output inst_invtlb, 56 | input [`WS_TO_ES_BUS_WD -1:0] ws_to_es_bus 57 | ); 58 | 59 | /* -------------- Handshaking signals -------------- */ 60 | 61 | reg es_valid ; 62 | wire es_ready_go ; 63 | 64 | assign invtlb_op = invop; 65 | 66 | /* ------------------- BUS ------------------- */ 67 | reg [`DS_TO_ES_BUS_WD -1:0] ds_to_es_bus_r; 68 | 69 | 70 | 71 | /*-------------------- Address translation --------------------*/ 72 | wire [31:0] badvaddr; 73 | wire [31:0] vaddr; 74 | wire [31:0] paddr; 75 | wire [19:0] vpn = vaddr[31:12]; 76 | wire [21:0] offset = vaddr[21:0]; 77 | 78 | wire dmw_hit = dmw0_hit || dmw1_hit; 79 | wire dmw0_hit; 80 | wire dmw1_hit; 81 | wire [31:0] dmw_addr; 82 | wire [31:0] tlb_addr; 83 | 84 | wire [31:0] csr_crmd_rvalue; 85 | wire [31:0] csr_dmw0_rvalue; 86 | wire [31:0] csr_dmw1_rvalue; 87 | wire [31:0] csr_asid_rvalue; 88 | wire [31:0] csr_tlbehi_rvalue; 89 | 90 | 91 | 92 | wire csr_crmd_da = csr_crmd_rvalue[`CSR_CRMD_DA]; 93 | wire csr_crmd_pg = csr_crmd_rvalue[`CSR_CRMD_PG]; 94 | wire [1:0] csr_crmd_plv = csr_crmd_rvalue[`CSR_CRMD_PLV]; 95 | wire csr_dmw0_plv0 = csr_dmw0_rvalue[`CSR_DMW_PLV0]; 96 | wire csr_dmw0_plv3 = csr_dmw0_rvalue[`CSR_DMW_PLV3]; 97 | wire [2:0] csr_dmw0_vseg = csr_dmw0_rvalue[`CSR_DMW_VSEG]; 98 | wire [2:0] csr_dmw0_pseg = csr_dmw0_rvalue[`CSR_DMW_PSEG]; 99 | wire csr_dmw1_plv0 = csr_dmw1_rvalue[`CSR_DMW_PLV0]; 100 | wire csr_dmw1_plv3 = csr_dmw1_rvalue[`CSR_DMW_PLV3]; 101 | wire [2:0] csr_dmw1_vseg = csr_dmw1_rvalue[`CSR_DMW_VSEG]; 102 | wire [2:0] csr_dmw1_pseg = csr_dmw1_rvalue[`CSR_DMW_PSEG]; 103 | wire [9:0] csr_asid_asid = csr_asid_rvalue[`CSR_ASID_ASID]; 104 | 105 | /* -------------- MEM write interface -------------- */ 106 | 107 | // Add in Lab 7 108 | wire es_op_ld_w ; 109 | wire es_op_ld_b ; 110 | wire es_op_ld_bu ; 111 | wire es_op_ld_h ; 112 | wire es_op_ld_hu ; 113 | wire es_op_st_b ; 114 | wire es_op_st_h ; 115 | wire es_op_st_w ; 116 | wire es_res_from_mem; 117 | wire es_op_mem = es_op_ld_w ||es_op_ld_b || es_op_ld_bu || es_op_ld_h || es_op_ld_hu || es_op_st_b || es_op_st_h || es_op_st_w; 118 | 119 | wire es_addr00; 120 | wire es_addr01; 121 | wire es_addr10; 122 | wire es_addr11; 123 | 124 | wire [3:0] data_sram_wstrb_sp; 125 | 126 | 127 | 128 | /* -------------- ALU -------------- */ 129 | 130 | wire [31:0] es_alu_src1 ; 131 | wire [31:0] es_alu_src2 ; 132 | wire [31:0] es_alu_result ; 133 | wire alu_ready_go ; 134 | wire [18:0] es_alu_op ; 135 | wire es_src1_is_pc ; 136 | wire es_src2_is_imm; 137 | wire es_gr_we ; 138 | wire es_mem_we ; 139 | 140 | wire [ 4:0] es_dest ; 141 | wire [31:0] es_imm ; 142 | wire [31:0] es_rj_value ; 143 | wire [31:0] es_rkd_value ; 144 | wire [31:0] es_pc ; 145 | 146 | alu u_alu( 147 | .clk (clk ), 148 | .reset (reset ), 149 | .alu_op (es_alu_op ), 150 | .alu_src1 (es_alu_src1 ), 151 | .alu_src2 (es_alu_src2 ), 152 | .alu_result (es_alu_result), 153 | .div_ready_go (alu_ready_go) 154 | ); 155 | 156 | //{19{es_valid}} 157 | 158 | /* -------------- Counter -------------- */ 159 | 160 | wire [ 2:0] es_rdcnt; 161 | 162 | wire es_inst_rdcntid; 163 | wire es_inst_rdcntvh_w; 164 | wire es_inst_rdcntvl_w; 165 | 166 | wire [31:0] es_cnt_result; 167 | wire [31:0] es_final_result; 168 | 169 | 170 | 171 | 172 | /* ------------------- Exceptions ------------------- */ 173 | 174 | wire ds_ex; 175 | wire [ 5:0] ds_ecode; 176 | wire ds_esubcode; 177 | 178 | wire es_ex; 179 | wire es_ertn_flush; 180 | wire es_esubcode; 181 | wire [ 5:0] es_ecode; 182 | 183 | wire ale_ex; 184 | 185 | reg es_ex_detected_unsolved; 186 | wire es_tlb_refetch; 187 | wire fs_tlb_refill_ex; 188 | wire es_tlb_refill_ex; 189 | wire es_tlb_load_invalid_ex; 190 | wire es_tlb_store_invalid_ex; 191 | wire es_tlb_modify_ex; 192 | wire es_tlb_ppe_ex; 193 | wire es_adem_ex; 194 | /* ------------------- CSR related ------------------- */ 195 | 196 | wire es_csr_block; 197 | 198 | wire [13:0] es_csr_num; 199 | wire es_csr_re; 200 | wire [31:0] es_csr_wmask; 201 | wire [31:0] es_csr_wvalue; 202 | wire es_csr_we; 203 | 204 | 205 | 206 | assign es_csr_block = es_valid & es_csr_re; 207 | 208 | wire [ 4:0] invop; 209 | 210 | /* -------------- Handshaking signals -------------- */ 211 | 212 | assign es_ready_go = ~es_op_mem ? alu_ready_go : alu_ready_go && (data_sram_req && data_sram_addr_ok) || 213 | (ale_ex | es_tlb_load_invalid_ex | es_tlb_store_invalid_ex | es_tlb_modify_ex | es_tlb_ppe_ex | es_adem_ex); 214 | assign es_allowin = !es_valid || es_ready_go && ms_allowin; 215 | assign es_to_ms_valid = es_valid && es_ready_go;//!!! 216 | 217 | always @(posedge clk) begin 218 | if (reset | final_ex | back_ertn_flush) begin 219 | es_valid <= 1'b0; 220 | end 221 | else if (es_allowin) begin 222 | es_valid <= ds_to_es_valid; 223 | end 224 | end 225 | 226 | /* ------------------- BUS ------------------- */ 227 | 228 | always @(posedge clk) begin 229 | if (ds_to_es_valid && es_allowin) begin 230 | ds_to_es_bus_r <= ds_to_es_bus; 231 | end 232 | end 233 | 234 | 235 | assign {fs_tlb_refill_ex, //268 236 | invop , //267:263 237 | es_tlb_refetch , //262 238 | inst_tlbsrch , //261 239 | inst_tlbrd , //260 240 | inst_tlbwr , //259 241 | inst_tlbfill , //258 242 | inst_invtlb , //257 243 | es_rdcnt , //256:254 244 | es_ertn_flush , //253 245 | ds_esubcode , //252 246 | ds_ecode , //251:246 247 | ds_ex } //245 248 | = ds_to_es_bus_r[268:245]; 249 | 250 | // When INE happens at ID stage, these signals are invalid 251 | assign {es_csr_re , //244 252 | es_csr_num , //243:230 253 | es_csr_wvalue , //229:198 254 | es_csr_wmask , //197:166 255 | es_csr_we , //165 256 | es_op_st_w , //164 257 | es_op_ld_w , //163 258 | es_op_ld_b , //162 259 | es_op_ld_bu , //161 260 | es_op_ld_h , //160 261 | es_op_ld_hu , //159 262 | es_op_st_b , //158 263 | es_op_st_h , //157 264 | es_alu_op , //156:138 265 | es_res_from_mem, //137:137 266 | es_src1_is_pc , //136:136 267 | es_src2_is_imm , //135:135 268 | es_gr_we , //134:134 269 | es_mem_we , //133:133 270 | es_dest , //132:128 271 | es_imm , //127:96 272 | es_rj_value , //95 :64 273 | es_rkd_value } //63 :32 274 | = ds_to_es_bus_r[244:32] & {213{~(ds_ecode == `ECODE_INE)}}; 275 | 276 | assign es_pc //31 :0 277 | = ds_to_es_bus_r[31:0]; 278 | 279 | // ES to MS bus 280 | assign es_to_ms_bus = {badvaddr , //210:179 281 | es_mem_ex , //178 282 | es_tlb_refill_ex, //177 283 | es_tlb_refetch , //176 284 | inst_tlbsrch , //175 285 | inst_tlbrd , //174 286 | inst_tlbwr , //173 287 | inst_tlbfill , //172 288 | inst_invtlb , //171 289 | es_op_st_w , //170 290 | es_inst_rdcntid, //169 291 | es_ertn_flush , //168 292 | es_esubcode , //167 293 | es_ecode , //166:161 294 | es_ex&es_valid , //160 295 | es_csr_re , //159 296 | es_csr_num , //158:145 297 | es_csr_wvalue , //144:113 298 | es_csr_wmask , //112:81 299 | es_csr_we , //80 300 | data_sram_addr[1:0], //79:78 301 | es_op_ld_w , //77 302 | es_op_ld_b , //76 303 | es_op_ld_bu , //75 304 | es_op_ld_h , //74 305 | es_op_ld_hu , //73 306 | es_op_st_b , //72 307 | es_op_st_h , //71 308 | es_res_from_mem & ~ale_ex, //70:70 309 | es_gr_we , //69:69 310 | es_dest , //68:64 311 | es_final_result , //63:32 312 | es_pc //31:0 313 | }; 314 | 315 | 316 | // ES forward bus 317 | assign es_forward = {es_csr_block, 318 | es_csr_re, //57 319 | es_csr_num, //56:43 320 | es_csr_we, //42 321 | es_ertn_flush, //41 322 | es_ex, //40 323 | es_res_from_mem,//39 324 | es_alu_result,//38:7 325 | es_dest , //6:2 326 | es_gr_we, //1:1 327 | es_valid //0:0 328 | }; 329 | 330 | assign {csr_crmd_rvalue, //159:128 331 | csr_dmw0_rvalue, //127:96 332 | csr_dmw1_rvalue, //95:64 333 | csr_asid_rvalue, //63:32 334 | csr_tlbehi_rvalue//31:0 335 | } = ws_to_es_bus; 336 | 337 | 338 | /* -------------- MEM write interface -------------- */ 339 | 340 | assign data_sram_req = (es_res_from_mem || es_mem_we) && es_valid 341 | && ~back_ertn_flush && ~(ms_ertn_flush && ms_to_es_valid) && ~(ale_ex | es_tlb_load_invalid_ex | es_tlb_store_invalid_ex | es_tlb_modify_ex | es_tlb_ppe_ex | es_adem_ex) 342 | && ms_allowin; 343 | 344 | assign data_sram_size = {2{es_op_st_b || es_op_ld_b || es_op_ld_bu}} & 2'b00 | 345 | {2{es_op_st_h || es_op_ld_h || es_op_ld_hu}} & 2'b01 | 346 | {2{es_op_st_w || es_op_ld_w}} & 2'b10; 347 | 348 | 349 | // Change in Lab 7 350 | assign es_addr00 = data_sram_addr[1:0] == 2'b00; 351 | assign es_addr01 = data_sram_addr[1:0] == 2'b01; 352 | assign es_addr10 = data_sram_addr[1:0] == 2'b10; 353 | assign es_addr11 = data_sram_addr[1:0] == 2'b11; 354 | assign data_sram_wstrb_sp= {4{es_op_st_b && es_addr00}} & 4'b0001 | 355 | {4{es_op_st_b && es_addr01}} & 4'b0010 | 356 | {4{es_op_st_b && es_addr10}} & 4'b0100 | 357 | {4{es_op_st_b && es_addr11}} & 4'b1000 | 358 | {4{es_op_st_h && es_addr00}} & 4'b0011 | 359 | {4{es_op_st_h && es_addr10}} & 4'b1100 | 360 | {4{es_op_st_w}} & 4'b1111; 361 | 362 | assign data_sram_wstrb = es_mem_we & ~ale_ex ? data_sram_wstrb_sp : 4'h0; 363 | assign data_sram_addr = paddr; 364 | assign data_sram_wdata = {32{es_op_st_b}} & {4{es_rkd_value[ 7:0]}} | 365 | {32{es_op_st_h}} & {2{es_rkd_value[15:0]}} | 366 | {32{es_op_st_w}} & es_rkd_value[31:0]; 367 | assign data_sram_wr = (|data_sram_wstrb) & ~es_tlb_refetch; 368 | 369 | /* -------------- ALU -------------- */ 370 | 371 | assign es_alu_src1 = es_src1_is_pc ? es_pc[31:0] : es_rj_value; 372 | assign es_alu_src2 = es_src2_is_imm ? es_imm : es_rkd_value; 373 | 374 | 375 | 376 | /* -------------- Counter -------------- */ 377 | 378 | assign es_inst_rdcntid = es_rdcnt[2]; 379 | assign es_inst_rdcntvh_w = es_rdcnt[1]; 380 | assign es_inst_rdcntvl_w = es_rdcnt[0]; 381 | 382 | assign es_cnt_result = es_inst_rdcntid | es_inst_rdcntvh_w ? es_counter[63:32] : es_counter[31:0]; 383 | 384 | 385 | assign es_final_result = es_inst_rdcntvh_w | es_inst_rdcntvl_w ? es_cnt_result : es_alu_result; 386 | 387 | 388 | 389 | /* ------------------- Exceptions ------------------- */ 390 | 391 | assign es_esubcode = es_adem_ex ? 1'b1 : ds_esubcode; 392 | assign es_ex = ale_ex | es_tlb_load_invalid_ex | es_tlb_store_invalid_ex | es_tlb_modify_ex | es_tlb_ppe_ex | es_adem_ex | ds_ex | es_tlb_refill_ex; 393 | assign es_ecode = ale_ex ? `ECODE_ALE : 394 | es_tlb_refill_ex ? `ECODE_TLBR : 395 | es_tlb_load_invalid_ex ? `ECODE_PIL : 396 | es_tlb_store_invalid_ex ? `ECODE_PIS : 397 | es_tlb_modify_ex ? `ECODE_PME : 398 | es_tlb_ppe_ex ? `ECODE_PPE : 399 | es_adem_ex ? `ECODE_ADE : 400 | ds_ecode; 401 | 402 | // Add in Lab 9 403 | // ALE exception 404 | assign ale_ex = (es_op_ld_h || es_op_ld_hu || es_op_st_h) && data_sram_addr[0] || 405 | (es_op_ld_w || es_op_st_w ) && (data_sram_addr[1:0] != 2'b00); 406 | 407 | 408 | always @(posedge clk) begin 409 | if (reset) 410 | es_ex_detected_unsolved <= 1'b0; 411 | else if (ms_to_es_ex) 412 | es_ex_detected_unsolved <= 1'b0; 413 | else if ((ale_ex | es_tlb_load_invalid_ex | es_tlb_store_invalid_ex | es_tlb_modify_ex | es_tlb_ppe_ex | es_adem_ex) && ~final_ex) 414 | es_ex_detected_unsolved <= 1'b1; 415 | else 416 | es_ex_detected_unsolved <= 1'b0; 417 | end 418 | 419 | assign es_ex_detected_to_fs = es_ex_detected_unsolved; 420 | 421 | /*-------------------- Address translation --------------------*/ 422 | assign vaddr = es_alu_result; 423 | 424 | // TLB 425 | 426 | assign s1_vppn = inst_invtlb ? es_rkd_value[31:13] : 427 | inst_tlbsrch ? csr_tlbehi_rvalue[31:13] : 428 | vpn[19:1]; 429 | assign s1_asid = inst_invtlb ? es_rj_value[9:0] : csr_asid_rvalue[9:0]; 430 | assign s1_va_bit12 = inst_invtlb ? es_rkd_value[12]: 431 | inst_tlbsrch ? 1'b0 : vpn[0]; 432 | 433 | assign tlb_addr = (s1_ps == 6'd12) ? {s1_ppn[19:0], offset[11:0]} : 434 | {s1_ppn[19:10], offset[21:0]}; 435 | 436 | assign da_hit = (csr_crmd_da == 1) && (csr_crmd_pg == 0); 437 | 438 | // DMW 439 | assign dmw0_hit = (csr_crmd_plv == 2'b00 && csr_dmw0_plv0 || 440 | csr_crmd_plv == 2'b11 && csr_dmw0_plv3 ) && (vaddr[31:29] == csr_dmw0_vseg); 441 | assign dmw1_hit = (csr_crmd_plv == 2'b00 && csr_dmw1_plv0 || 442 | csr_crmd_plv == 2'b11 && csr_dmw1_plv3 ) && (vaddr[31:29] == csr_dmw1_vseg); 443 | 444 | assign dmw_addr = {32{dmw0_hit}} & {csr_dmw0_pseg, vaddr[28:0]} | 445 | {32{dmw1_hit}} & {csr_dmw1_pseg, vaddr[28:0]}; 446 | 447 | // PADDR 448 | assign paddr = da_hit ? vaddr : 449 | dmw_hit ? dmw_addr : 450 | tlb_addr; 451 | assign es_tlb_refill_ex = ~da_hit & ~dmw_hit & (es_mem_we | es_res_from_mem) & ~s1_found | fs_tlb_refill_ex; 452 | assign es_tlb_load_invalid_ex = ~da_hit & ~dmw_hit & es_res_from_mem & s1_found & ~s1_v; 453 | assign es_tlb_store_invalid_ex = ~da_hit & ~dmw_hit & es_mem_we & s1_found & ~s1_v; 454 | assign es_tlb_modify_ex = ~da_hit & ~dmw_hit & es_mem_we & s1_found & s1_v & ~es_tlb_ppe_ex & ~s1_d; 455 | assign es_tlb_ppe_ex = ~da_hit & ~dmw_hit & (es_mem_we | es_res_from_mem) & s1_found & s1_v & csr_crmd_plv == 2'b11 && s1_plv == 2'b00; 456 | assign es_adem_ex = ~da_hit & ~dmw_hit & (es_mem_we | es_res_from_mem) & csr_crmd_plv == 2'b11 & vaddr[31]; 457 | 458 | wire es_mem_ex = ~da_hit & ~dmw_hit & (es_mem_we | es_res_from_mem) & ~s1_found || 459 | es_tlb_load_invalid_ex || 460 | es_tlb_store_invalid_ex || 461 | es_tlb_modify_ex || 462 | es_tlb_ppe_ex || 463 | es_adem_ex || 464 | ale_ex; 465 | 466 | assign badvaddr = ds_ex ? es_pc : es_alu_result; 467 | endmodule 468 | -------------------------------------------------------------------------------- /id_stage.v: -------------------------------------------------------------------------------- 1 | `include "mycpu.h" 2 | 3 | module id_stage( 4 | input clk , 5 | input reset , 6 | //allowin 7 | input es_allowin , 8 | output ds_allowin , 9 | //from fs 10 | input fs_to_ds_valid, 11 | input [`FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus , 12 | //to es 13 | output ds_to_es_valid, 14 | output [`DS_TO_ES_BUS_WD -1:0] ds_to_es_bus , 15 | //to fs 16 | output [`BR_BUS_WD -1:0] br_bus , 17 | //to rf: for write back 18 | input [`WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus , 19 | input [`ES_FORWARD_WD -1:0] es_forward, 20 | input [`MS_FORWARD_WD -1:0] ms_forward, 21 | input [`WS_FORWARD_WD -1:0] ws_forward, 22 | input back_ertn_flush, 23 | input back_ex 24 | ); 25 | 26 | /* -------------- Instruction Decoder -------------- */ 27 | 28 | wire [18:0] alu_op; 29 | wire src1_is_pc; 30 | wire src2_is_imm; 31 | wire res_from_mem; 32 | wire src_reg_is_rd; 33 | 34 | wire [31:0] ds_imm; 35 | wire [31:0] br_offs; 36 | wire [31:0] jirl_offs; 37 | 38 | wire [ 5:0] op_31_26; 39 | wire [ 3:0] op_25_22; 40 | wire [ 1:0] op_21_20; 41 | wire [ 4:0] op_19_15; 42 | wire [ 4:0] op_14_10; 43 | 44 | wire [ 4:0] rd; 45 | wire [ 4:0] rj; 46 | wire [ 4:0] rk; 47 | wire [11:0] i12; 48 | wire [19:0] i20; 49 | wire [15:0] i16; 50 | wire [25:0] i26; 51 | 52 | wire [63:0] op_31_26_d; 53 | wire [15:0] op_25_22_d; 54 | wire [ 3:0] op_21_20_d; 55 | wire [31:0] op_19_15_d; 56 | wire [31:0] op_14_10_d; 57 | 58 | // Instructions 59 | wire inst_add_w; 60 | wire inst_sub_w; 61 | wire inst_slt; 62 | wire inst_sltu; 63 | wire inst_nor; 64 | wire inst_and; 65 | wire inst_or; 66 | wire inst_xor; 67 | wire inst_slli_w; 68 | wire inst_srli_w; 69 | wire inst_srai_w; 70 | wire inst_addi_w; 71 | wire inst_ld_w; 72 | wire inst_st_w; 73 | wire inst_jirl; 74 | wire inst_b; 75 | wire inst_bl; 76 | wire inst_beq; 77 | wire inst_bne; 78 | wire inst_lu12i_w; 79 | 80 | // Add in Lab 6 81 | wire inst_slti; 82 | wire inst_sltui; 83 | wire inst_andi; 84 | wire inst_ori; 85 | wire inst_xori; 86 | wire inst_sll_w; 87 | wire inst_srl_w; 88 | wire inst_sra_w; 89 | wire inst_pcaddu12i; 90 | wire inst_mul_w; 91 | wire inst_mulh_w; 92 | wire inst_mulh_wu; 93 | wire inst_div_w; 94 | wire inst_mod_w; 95 | wire inst_div_wu; 96 | wire inst_mod_wu; 97 | 98 | // Add in Lab 7 99 | wire inst_blt; 100 | wire inst_bge; 101 | wire inst_bltu; 102 | wire inst_bgeu; 103 | wire inst_ld_b; 104 | wire inst_ld_h; 105 | wire inst_ld_bu; 106 | wire inst_ld_hu; 107 | wire inst_st_b; 108 | wire inst_st_h; 109 | wire inst_mem; 110 | 111 | // Add in Lab 8 112 | wire inst_csrrd; 113 | wire inst_csrwr; 114 | wire inst_csrxchg; 115 | wire inst_ertn; 116 | wire inst_syscall; 117 | 118 | // Add in Lab 9 119 | wire inst_break; 120 | wire inst_rdcntid; 121 | wire inst_rdcntvh_w; 122 | wire inst_rdcntvl_w; 123 | 124 | // Add in Lab 14 125 | wire inst_tlbsrch; 126 | wire inst_tlbrd; 127 | wire inst_tlbwr; 128 | wire inst_tlbfill; 129 | wire inst_invtlb; 130 | 131 | reg tlb_refetch; 132 | 133 | // Load/Store signals 134 | // Add in Lab 7 135 | wire op_ld_w; 136 | wire op_ld_b; 137 | wire op_ld_bu; 138 | wire op_ld_h; 139 | wire op_ld_hu; 140 | wire op_st_b; 141 | wire op_st_h; 142 | wire op_st_w; 143 | 144 | // CSR instruction related signals 145 | wire [13:0] csr_num; 146 | wire csr_re; 147 | wire [31:0] csr_wmask; //rj 148 | wire [31:0] csr_wvalue; //rd 149 | wire csr_we; 150 | 151 | wire need_ui5; 152 | wire need_si12; 153 | wire need_si16; 154 | wire need_si20; 155 | wire need_si26; 156 | wire src2_is_4; 157 | 158 | 159 | 160 | 161 | /* -------------- Adder for comparison -------------- */ 162 | // Add in Lab 7 163 | wire rj_eq_rd; 164 | wire rj_lt_rd; 165 | wire rj_ltu_rd; 166 | 167 | wire sign_bit; 168 | wire [31:0] out; 169 | wire overflow; 170 | 171 | 172 | /* -------------- Handshaking signals -------------- */ 173 | 174 | reg ds_valid ; 175 | wire ds_ready_go; 176 | wire csr_block; 177 | 178 | wire ds_tlb_refetch; 179 | wire tlb_reflush; 180 | /* ------------------- BUS ------------------- */ 181 | 182 | // FS to DS bus 183 | reg [`FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus_r; 184 | 185 | wire [31:0] ds_inst; 186 | wire [31:0] ds_pc ; 187 | wire fs_esubcode; 188 | wire [ 5:0] fs_ecode; 189 | wire fs_ex; 190 | wire fs_tlb_refill_ex; 191 | // WS to RF bus 192 | wire rf_we ; 193 | wire [ 4:0] rf_waddr; 194 | wire [31:0] rf_wdata; 195 | 196 | // ES forward bus 197 | wire es_ertn_flush; 198 | wire es_ex; 199 | wire es_res_from_mem; 200 | wire [31:0] es_alu_result; 201 | wire [13:0] es_csr_num; 202 | wire es_csr_re; 203 | wire [4:0] es_dest; 204 | wire es_csr_we; 205 | wire es_gr_we; 206 | wire es_valid; 207 | wire es_csr_block; 208 | 209 | // MS forward bus 210 | wire ms_data_sram_data_ok; 211 | wire ms_ertn_flush; 212 | wire ms_ex; 213 | wire ms_res_from_mem; 214 | wire [31:0] ms_final_result; 215 | wire [13:0] ms_csr_num; 216 | wire ms_csr_re; 217 | wire [4:0] ms_dest; 218 | wire ms_csr_we; 219 | wire ms_gr_we; 220 | wire ms_valid; 221 | wire ms_csr_block; 222 | 223 | // WS forward bus 224 | wire has_int; 225 | wire [31:0] ex_era; 226 | wire [31:0] ex_entry; 227 | wire ws_ertn_flush; 228 | wire ws_ex; 229 | wire final_ex; 230 | wire [31:0] ws_final_result; 231 | wire [13:0] ws_csr_num; 232 | wire ws_csr_re; 233 | wire [ 4:0] ws_dest; 234 | wire ws_csr_we; 235 | wire ws_rf_we; 236 | wire ws_valid; 237 | wire [ 2:0] ds_rdcnt; 238 | 239 | 240 | 241 | /* ------------------- Branch ------------------- */ 242 | 243 | wire br_taken; 244 | wire [31:0] br_target; 245 | 246 | 247 | 248 | /* ------------------- Exceptions ------------------- */ 249 | // Add in Lab 8 & Lab 9 250 | 251 | wire ds_ex; 252 | wire [ 5:0] ds_ecode; 253 | wire ds_esubcode; 254 | 255 | // INE exception 256 | wire ine_ex; 257 | 258 | reg ex_detected_unsolved; 259 | wire ex_detected_to_fs; 260 | 261 | /* ------------------- Regfile Interface ------------------- */ 262 | 263 | wire dst_is_r1; 264 | wire gr_we; 265 | wire mem_we; 266 | wire [4: 0] dest; 267 | 268 | wire [ 4:0] rf_raddr1; 269 | wire [31:0] rf_rdata1; 270 | wire [ 4:0] rf_raddr2; 271 | wire [31:0] rf_rdata2; 272 | 273 | 274 | 275 | /* ------------------- RAW Conflict ------------------- */ 276 | wire [31:0] rj_value; 277 | wire [31:0] rkd_value; 278 | 279 | wire no_src1; 280 | wire no_src2; 281 | 282 | wire [4:0] src1; 283 | wire [4:0] src2; 284 | 285 | wire raw1; 286 | wire raw2; 287 | wire raw3; 288 | wire raw4; 289 | wire raw5; 290 | wire raw6; 291 | wire raw; 292 | 293 | wire br_stall; 294 | 295 | wire [4:0] invop; 296 | /* ------------------------------------------ ASSIGNMENTS ------------------------------------------ */ 297 | 298 | 299 | /* -------------- Instruction Decoder -------------- */ 300 | 301 | assign op_31_26 = ds_inst[31:26]; 302 | assign op_25_22 = ds_inst[25:22]; 303 | assign op_21_20 = ds_inst[21:20]; 304 | assign op_19_15 = ds_inst[19:15]; 305 | assign op_14_10 = ds_inst[14:10]; 306 | 307 | assign rd = ds_inst[ 4: 0]; 308 | assign rj = ds_inst[ 9: 5]; 309 | assign rk = ds_inst[14:10]; 310 | 311 | assign invop = ds_inst[ 4:0]; 312 | 313 | assign i12 = ds_inst[21:10]; 314 | assign i20 = ds_inst[24: 5]; 315 | assign i16 = ds_inst[25:10]; 316 | assign i26 = {ds_inst[ 9: 0], ds_inst[25:10]}; 317 | 318 | decoder_6_64 u_dec0(.in(op_31_26 ), .out(op_31_26_d )); 319 | decoder_4_16 u_dec1(.in(op_25_22 ), .out(op_25_22_d )); 320 | decoder_2_4 u_dec2(.in(op_21_20 ), .out(op_21_20_d )); 321 | decoder_5_32 u_dec3(.in(op_19_15 ), .out(op_19_15_d )); 322 | decoder_5_32 u_dec4(.in(op_14_10 ), .out(op_14_10_d )); 323 | 324 | assign inst_add_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h00]; 325 | assign inst_sub_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h02]; 326 | assign inst_slt = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h04]; 327 | assign inst_sltu = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h05]; 328 | assign inst_nor = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h08]; 329 | assign inst_and = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h09]; 330 | assign inst_or = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0a]; 331 | assign inst_xor = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0b]; 332 | assign inst_slli_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h01]; 333 | assign inst_srli_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h09]; 334 | assign inst_srai_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h11]; 335 | assign inst_addi_w = op_31_26_d[6'h00] & op_25_22_d[4'ha]; 336 | assign inst_ld_w = op_31_26_d[6'h0a] & op_25_22_d[4'h2]; 337 | assign inst_st_w = op_31_26_d[6'h0a] & op_25_22_d[4'h6]; 338 | assign inst_jirl = op_31_26_d[6'h13]; 339 | assign inst_b = op_31_26_d[6'h14]; 340 | assign inst_bl = op_31_26_d[6'h15]; 341 | assign inst_beq = op_31_26_d[6'h16]; 342 | assign inst_bne = op_31_26_d[6'h17]; 343 | assign inst_lu12i_w= op_31_26_d[6'h05] & ~ds_inst[25]; 344 | 345 | //Add in lab6 346 | assign inst_slti = op_31_26_d[6'h00] & op_25_22_d[4'h8]; //0000001000 347 | assign inst_sltui = op_31_26_d[6'h00] & op_25_22_d[4'h9]; //0000001001 348 | assign inst_andi = op_31_26_d[6'h00] & op_25_22_d[4'hd]; //0000001101 349 | assign inst_ori = op_31_26_d[6'h00] & op_25_22_d[4'he]; //0000001110 350 | assign inst_xori = op_31_26_d[6'h00] & op_25_22_d[4'hf]; //0000001111 351 | assign inst_sll_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0e]; //00000000000101110 352 | assign inst_srl_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0f]; //00000000000101111 353 | assign inst_sra_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h10]; //00000000000110000 354 | assign inst_pcaddu12i = op_31_26_d[6'h07] & ~ds_inst[25]; //0001110; 355 | assign inst_mul_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h18]; //00000000000111000 356 | assign inst_mulh_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h19]; //00000000000111001 357 | assign inst_mulh_wu= op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h1a]; //00000000000111010 358 | assign inst_div_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h00]; //00000000001000000 359 | assign inst_mod_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h01]; //00000000001000001 360 | assign inst_div_wu = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h02]; //00000000001000010 361 | assign inst_mod_wu = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h03]; //00000000001000011 362 | 363 | // Add in lab7 364 | assign inst_mem = op_31_26_d[6'h0a]; 365 | assign inst_blt = op_31_26_d[6'h18]; 366 | assign inst_bge = op_31_26_d[6'h19]; 367 | assign inst_bltu = op_31_26_d[6'h1a]; 368 | assign inst_bgeu = op_31_26_d[6'h1b]; 369 | assign inst_ld_b = op_31_26_d[6'h0a] & op_25_22_d[4'h0]; 370 | assign inst_ld_h = op_31_26_d[6'h0a] & op_25_22_d[4'h1]; 371 | assign inst_ld_bu = op_31_26_d[6'h0a] & op_25_22_d[4'h8]; 372 | assign inst_ld_hu = op_31_26_d[6'h0a] & op_25_22_d[4'h9]; 373 | assign inst_st_b = op_31_26_d[6'h0a] & op_25_22_d[4'h4]; 374 | assign inst_st_h = op_31_26_d[6'h0a] & op_25_22_d[4'h5]; 375 | 376 | // Add in lab8 377 | assign inst_csrrd = op_31_26_d[6'h01] && ~ds_inst[25] && ~ds_inst[24] && (rj==5'b00); //00000100 378 | assign inst_csrwr = op_31_26_d[6'h01] && ~ds_inst[25] && ~ds_inst[24] && (rj==5'b01); //00000100 379 | assign inst_csrxchg= op_31_26_d[6'h01] & ~ds_inst[25] & ~ds_inst[24] & ~inst_csrrd & ~inst_csrwr; //00000100 380 | assign inst_ertn = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & op_14_10_d[5'h0e] && (rj==5'b00) && (rd==5'b00); //0000011001001000001110 381 | assign inst_syscall= op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h16]; //00000000001010110 382 | 383 | // Add in lab9 384 | assign inst_break = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h2] & op_19_15_d[5'h14]; 385 | assign inst_rdcntvl_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h0] & op_19_15_d[5'h00] & (rk == 5'h18) & (rj == 5'h00); 386 | assign inst_rdcntvh_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h0] & op_19_15_d[5'h00] & (rk == 5'h19) & (rj == 5'h00); 387 | assign inst_rdcntid = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h0] & op_19_15_d[5'h00] & (rk == 5'h18) & (rd == 5'h00); 388 | assign op_ld_w = inst_ld_w; 389 | assign op_ld_b = inst_ld_b; 390 | assign op_ld_h = inst_ld_h; 391 | assign op_ld_bu = inst_ld_bu; 392 | assign op_ld_hu = inst_ld_hu; 393 | assign op_st_b = inst_st_b; 394 | assign op_st_h = inst_st_h; 395 | assign op_st_w = inst_st_w; 396 | 397 | // Add in lab14 398 | assign inst_tlbsrch = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & op_14_10_d[5'h0a] && (rj==5'b00) && (rd==5'b00); 399 | assign inst_tlbrd = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & op_14_10_d[5'h0b] && (rj==5'b00) && (rd==5'b00); 400 | assign inst_tlbwr = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & op_14_10_d[5'h0c] && (rj==5'b00) && (rd==5'b00); 401 | assign inst_tlbfill = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h10] & op_14_10_d[5'h0d] && (rj==5'b00) && (rd==5'b00); 402 | assign inst_invtlb = op_31_26_d[6'h01] & op_25_22_d[4'h9] & op_21_20_d[2'h0] & op_19_15_d[5'h13] & (invop==5'h00 | invop==5'h01 | invop==5'h02 | invop==5'h03 | invop==5'h04 | invop==5'h05 | invop==5'h06); 403 | 404 | assign alu_op[ 0] = inst_add_w | inst_addi_w | inst_mem | inst_jirl | inst_bl | inst_pcaddu12i; 405 | assign alu_op[ 1] = inst_sub_w; 406 | assign alu_op[ 2] = inst_slt | inst_slti; 407 | assign alu_op[ 3] = inst_sltu | inst_sltui; 408 | assign alu_op[ 4] = inst_and | inst_andi; 409 | assign alu_op[ 5] = inst_nor; 410 | assign alu_op[ 6] = inst_or | inst_ori; 411 | assign alu_op[ 7] = inst_xor | inst_xori; 412 | assign alu_op[ 8] = inst_slli_w | inst_sll_w; 413 | assign alu_op[ 9] = inst_srli_w | inst_srl_w; 414 | assign alu_op[10] = inst_srai_w | inst_sra_w; 415 | assign alu_op[11] = inst_lu12i_w; 416 | assign alu_op[12] = inst_mul_w; 417 | assign alu_op[13] = inst_mulh_w; 418 | assign alu_op[14] = inst_mulh_wu; 419 | assign alu_op[15] = inst_div_w; 420 | assign alu_op[16] = inst_div_wu; 421 | assign alu_op[17] = inst_mod_w; 422 | assign alu_op[18] = inst_mod_wu; 423 | 424 | assign res_from_mem = inst_ld_w | inst_ld_b | inst_ld_bu | inst_ld_h | inst_ld_hu; 425 | assign need_ui5 = inst_slli_w | inst_srli_w | inst_srai_w; 426 | assign need_si12 = inst_addi_w | inst_slti | inst_sltui | inst_andi | inst_ori | inst_xori //slti, sltui, andi, ori, xori use addi.w in id stage 427 | | inst_mem; 428 | assign need_si16 = inst_jirl | inst_beq | inst_bne | inst_blt | inst_bge | inst_bltu | inst_bgeu; 429 | assign need_si20 = inst_lu12i_w | inst_pcaddu12i; //pcaddu12i: PC+{si20, 12'b0}, uses lu12i.w in id stage 430 | assign need_si26 = inst_b | inst_bl; 431 | assign src2_is_4 = inst_jirl | inst_bl; 432 | 433 | assign ds_imm = src2_is_4 ? 32'h4 : 434 | need_si20 ? {i20[19:0], 12'b0} : //i20[16:5]==i12[11:0] 435 | inst_andi | inst_ori | inst_xori ? {20'b0,i12[11:0]} : // (rj) zero extension 436 | /*need_ui5 || need_si12*/ {{20{i12[11]}}, i12[11:0]} ; 437 | 438 | assign br_offs = need_si26 ? {{ 4{i26[25]}}, i26[25:0], 2'b0} : 439 | {{14{i16[15]}}, i16[15:0], 2'b0} ; 440 | 441 | assign jirl_offs = {{14{i16[15]}}, i16[15:0], 2'b0}; 442 | 443 | assign src_reg_is_rd = inst_beq | inst_bne | inst_blt | inst_bge | inst_bltu | 444 | inst_bgeu | inst_st_w | inst_st_b | inst_st_h| 445 | inst_csrrd | inst_csrwr | inst_csrxchg; 446 | 447 | assign src1_is_pc = inst_jirl | inst_bl | inst_pcaddu12i; 448 | 449 | assign src2_is_imm = inst_slli_w | 450 | inst_srli_w | 451 | inst_srai_w | 452 | inst_addi_w | 453 | inst_lu12i_w| 454 | inst_jirl | 455 | inst_bl | 456 | //add in lab6 457 | inst_slti | 458 | inst_sltui | 459 | inst_andi | 460 | inst_ori | 461 | inst_xori | 462 | inst_pcaddu12i | 463 | // add in lab7 464 | inst_mem; 465 | 466 | // CSR signals 467 | // Add in Lab 8 468 | assign csr_num = inst_rdcntid ? 14'd64 : ds_inst[23:10]; 469 | assign csr_we = inst_csrwr | inst_csrxchg && ~ds_tlb_refetch; 470 | assign csr_re = inst_csrrd | inst_csrwr | inst_csrxchg | inst_rdcntid && ~ds_tlb_refetch; 471 | assign csr_wmask = {32{inst_csrxchg}} & rj_value | {32{~inst_csrxchg}}; 472 | assign csr_wvalue = rkd_value; 473 | 474 | /* -------------- Adder for comparison -------------- */ 475 | 476 | assign {sign_bit, out} = {1'b0, rj_value} + {1'b1, ~rkd_value} + 33'd1; 477 | assign overflow = (rj_value[31] ^ rkd_value[31]) & (rj_value[31] ^ out[31]); 478 | assign rj_eq_rd = (rj_value == rkd_value); 479 | assign rj_lt_rd = out[31] ^ overflow; 480 | assign rj_ltu_rd = sign_bit; 481 | 482 | 483 | 484 | /* -------------- Handshaking signals -------------- */ 485 | 486 | assign ds_allowin = !ds_valid || ds_ready_go && es_allowin; 487 | assign ds_to_es_valid = ds_valid && ds_ready_go; 488 | 489 | always @(posedge clk) begin 490 | if (reset | final_ex | ws_ertn_flush) begin 491 | ds_valid <= 1'b0; 492 | end 493 | else if (br_taken) 494 | ds_valid <= 1'b0; 495 | else if (ds_allowin) begin 496 | ds_valid <= fs_to_ds_valid; 497 | end 498 | end 499 | 500 | assign load_block = es_valid && es_res_from_mem && (raw1 || raw4) || 501 | ms_valid && ms_res_from_mem && (raw2 || raw5) && ~ms_data_sram_data_ok; 502 | assign csr_block = es_csr_block & (raw1 | raw4) 503 | | ms_csr_block & (raw2 | raw5) 504 | | ws_valid & ws_csr_re & (raw3 | raw6) ; 505 | 506 | assign ds_ready_go = !load_block && 507 | !(!final_ex && ((es_valid && es_ex) || (ms_valid && ms_ex) || (ws_valid && ws_ex)) && ds_valid) && 508 | !(ds_valid && csr_block) && 509 | !(has_int && ((es_valid && (es_ertn_flush || (es_csr_we && (es_csr_num == `CSR_CRMD || es_csr_num == `CSR_ECFG )))) || 510 | (ms_valid && (ms_ertn_flush || (ms_csr_we && (ms_csr_num == `CSR_CRMD || ms_csr_num == `CSR_ECFG )))) || 511 | (ws_valid && (ws_ertn_flush || (ws_csr_we && (ws_csr_num == `CSR_CRMD || ws_csr_num == `CSR_ECFG )))) 512 | )) && ~csr_block; 513 | 514 | /* ------------------- lab10 ------------------- */ 515 | assign br_stall = es_valid && es_res_from_mem && (need_si16 && (raw1 || raw4) 516 | || need_si16 && (raw2 || raw5)); 517 | 518 | /* ------------------- BUS ------------------- */ 519 | 520 | // FS to DS bus 521 | always @(posedge clk) begin 522 | if (fs_to_ds_valid && ds_allowin) begin 523 | fs_to_ds_bus_r <= fs_to_ds_bus; 524 | end 525 | end 526 | 527 | assign {fs_tlb_refill_ex,//73 528 | ds_tlb_refetch,//72 529 | fs_esubcode , //71 530 | fs_ecode , //70:65 531 | fs_ex , //64 532 | ds_inst, 533 | ds_pc 534 | } = fs_to_ds_bus_r; 535 | 536 | // WS to RF bus 537 | assign {rf_we , //37:37 538 | rf_waddr, //36:32 539 | rf_wdata //31:0 540 | } = ws_to_rf_bus; 541 | 542 | // BR bus 543 | assign br_bus = {tlb_refetch || ((inst_tlbwr || inst_tlbrd || inst_tlbfill || inst_invtlb) && ds_valid) 544 | , ex_detected_to_fs, br_stall,br_taken,br_target}; 545 | 546 | // ES forward bus 547 | assign {es_csr_block, 548 | es_csr_re, //57 549 | es_csr_num, //56:43 550 | es_csr_we, //42 551 | es_ertn_flush, //41 552 | es_ex, //40 553 | es_res_from_mem,//39 554 | es_alu_result,//38:7 555 | es_dest , //6:2 556 | es_gr_we, //1:1 557 | es_valid //0:0 558 | } = es_forward; 559 | 560 | // MS forward bus 561 | assign {ms_res_from_mem, //59 562 | ms_data_sram_data_ok,//58 563 | ms_csr_block,//57 564 | ms_csr_re, //56 565 | ms_csr_num, //55:42 566 | ms_csr_we, //41 567 | ms_ertn_flush, //40 568 | ms_ex, //39 569 | ms_final_result, //38:7 570 | ms_dest , //6:2 571 | ms_gr_we, //1:1 572 | ms_valid //0:0 573 | } = ms_forward; 574 | 575 | // WS forward bus 576 | assign {tlb_reflush,//123 577 | has_int, //122 578 | ex_era, //121:90 579 | ex_entry, //89:58 580 | final_ex, //57 581 | ws_csr_re, //56 582 | ws_csr_num, //55:42 583 | ws_csr_we, //41 584 | ws_ertn_flush, //40 585 | ws_ex, //39 586 | ws_final_result, //38:7 587 | ws_dest , //6:2 588 | ws_rf_we, //1 589 | ws_valid //0 590 | } = ws_forward; 591 | 592 | // DS to ES bus 593 | 594 | // ds_rdcnt signal is the combination of three inst signals 595 | assign ds_rdcnt = {inst_rdcntid, inst_rdcntvh_w, inst_rdcntvl_w}; 596 | 597 | assign ds_to_es_bus = {fs_tlb_refill_ex,//268 598 | invop , //267:263 599 | ds_tlb_refetch,//262 600 | inst_tlbsrch, //261 601 | inst_tlbrd , //260 602 | inst_tlbwr , //259 603 | inst_tlbfill, //258 604 | inst_invtlb , //257 605 | ds_rdcnt , //256:254 606 | inst_ertn , //253 607 | ds_esubcode , //252 608 | ds_ecode , //251:246 609 | ds_ex & ds_valid, //245 610 | csr_re , //244 611 | csr_num , //243:230 612 | csr_wvalue , //229:198 613 | csr_wmask , //197:166 614 | csr_we , //165 615 | op_st_w , //164 616 | op_ld_w , //163 617 | op_ld_b , //162 618 | op_ld_bu , //161 619 | op_ld_h , //160 620 | op_ld_hu , //159 621 | op_st_b , //158 622 | op_st_h , //157 623 | alu_op , //156:138 624 | res_from_mem, //137:137 625 | src1_is_pc , //136:136 626 | src2_is_imm , //135:135 627 | gr_we , //134:134 628 | mem_we , //133:133 629 | dest , //132:128 630 | ds_imm , //127:96 631 | rj_value , //95 :64 632 | rkd_value , //63 :32 633 | ds_pc //31 :0 634 | }; 635 | 636 | 637 | /* ------------------- Branch ------------------- */ 638 | 639 | assign br_taken = ( inst_beq && rj_eq_rd 640 | || inst_bne && !rj_eq_rd 641 | || inst_blt && rj_lt_rd 642 | || inst_bge && !rj_lt_rd 643 | || inst_bltu && rj_ltu_rd 644 | || inst_bgeu && !rj_ltu_rd 645 | || inst_jirl 646 | || inst_bl 647 | || inst_b 648 | ) && ds_valid && ds_ready_go; 649 | assign br_target = inst_jirl ? (rj_value + jirl_offs) : (ds_pc + br_offs); 650 | 651 | 652 | 653 | 654 | /* ------------------- Regfile Interface ------------------- */ 655 | 656 | assign dst_is_r1 = inst_bl; 657 | assign dst_is_rj = inst_rdcntid; 658 | assign gr_we = ~inst_st_w & ~inst_st_b & ~inst_st_h & ~inst_beq & ~inst_bne & ~inst_blt & ~inst_bltu 659 | & ~inst_bge & ~inst_bgeu & ~inst_b & ~inst_ertn 660 | & ~inst_tlbsrch & ~inst_tlbrd & ~inst_tlbwr & ~inst_tlbfill &~inst_invtlb; 661 | assign mem_we = inst_st_w | inst_st_b | inst_st_h; 662 | assign dest = dst_is_r1 ? 5'd1 : 663 | dst_is_rj ? rj : rd; 664 | 665 | assign rf_raddr1 = rj; 666 | assign rf_raddr2 = src_reg_is_rd ? rd :rk; 667 | 668 | regfile u_regfile( 669 | .clk (clk ), 670 | .raddr1 (rf_raddr1), 671 | .rdata1 (rf_rdata1), 672 | .raddr2 (rf_raddr2), 673 | .rdata2 (rf_rdata2), 674 | .we (rf_we ), 675 | .waddr (rf_waddr ), 676 | .wdata (rf_wdata ) 677 | ); 678 | 679 | 680 | 681 | /* ------------------- RAW Conflict ------------------- */ 682 | 683 | 684 | assign no_src1 = inst_b || inst_bl || inst_pcaddu12i || 685 | inst_csrrd || inst_csrwr || inst_rdcntvl_w || inst_rdcntvh_w || inst_rdcntid; 686 | 687 | assign no_src2 = inst_b || inst_bl || inst_jirl || inst_addi_w || 688 | inst_ld_w || inst_ld_b || inst_ld_bu || inst_ld_h || inst_ld_hu || 689 | inst_slli_w || inst_srli_w || inst_srai_w || inst_slti || inst_sltui || 690 | inst_andi || inst_ori || inst_xori || inst_pcaddu12i || inst_csrrd || inst_rdcntvh_w || inst_rdcntid; 691 | 692 | assign src1 = no_src1 ? 5'd0 : rf_raddr1; 693 | assign src2 = no_src2 ? 5'd0 : rf_raddr2; 694 | 695 | assign raw1 = (src1 == es_dest) && (src1 != 5'd0) && (es_dest != 5'd0) && es_valid && es_gr_we; 696 | assign raw2 = (src1 == ms_dest) && (src1 != 5'd0) && (ms_dest != 5'd0) && ms_valid && ms_gr_we; 697 | assign raw3 = (src1 == ws_dest) && (src1 != 5'd0) && (ws_dest != 5'd0) && ws_rf_we ; 698 | assign raw4 = (src2 == es_dest) && (src2 != 5'd0) && (es_dest != 5'd0) && es_valid && es_gr_we; 699 | assign raw5 = (src2 == ms_dest) && (src2 != 5'd0) && (ms_dest != 5'd0) && ms_valid && ms_gr_we; 700 | assign raw6 = (src2 == ws_dest) && (src2 != 5'd0) && (ws_dest != 5'd0) && ws_rf_we ; 701 | 702 | assign raw = raw1 || raw2 || raw3 || raw4 || raw5 || raw6; 703 | 704 | assign rj_value = raw1 ? es_alu_result : 705 | raw2 ? ms_final_result : 706 | raw3 ? ws_final_result : rf_rdata1; 707 | 708 | assign rkd_value = raw4 ? es_alu_result : 709 | raw5 ? ms_final_result : 710 | raw6 ? ws_final_result : rf_rdata2; 711 | 712 | 713 | 714 | /* ------------------- Exceptions ------------------- */ 715 | 716 | assign ds_ex = ds_ready_go & (inst_syscall | inst_break | fs_ex | ine_ex | has_int) && ds_valid; 717 | assign ds_ecode = ~ds_valid ? 6'b0 : 718 | fs_ex ? fs_ecode : 719 | ine_ex ? `ECODE_INE : 720 | has_int ? `ECODE_INT : 721 | inst_syscall ? `ECODE_SYS : 722 | inst_ertn ? `ECODE_ERT : 723 | inst_break ? `ECODE_BRK : 6'b0; 724 | 725 | assign ds_esubcode = fs_esubcode; 726 | 727 | always @(posedge clk) begin 728 | if (reset) 729 | ex_detected_unsolved <= 1'b0; 730 | else if (ms_ex) 731 | ex_detected_unsolved <= 1'b0; 732 | else if (ds_ex && ~final_ex) 733 | ex_detected_unsolved <= 1'b1; 734 | else 735 | ex_detected_unsolved <= 1'b0; 736 | end 737 | 738 | assign ex_detected_to_fs = ex_detected_unsolved; 739 | 740 | always @(posedge clk) begin 741 | if (reset) 742 | tlb_refetch <= 1'b0; 743 | else if (tlb_reflush) 744 | tlb_refetch <= 1'b0; 745 | else if ((inst_tlbwr || inst_tlbrd || inst_tlbfill || inst_invtlb) && ds_valid) 746 | tlb_refetch <= 1'b1; 747 | end 748 | 749 | 750 | // INE exception 751 | // Add in Lab 9 752 | assign ine_ex = ~(inst_add_w | inst_sub_w | inst_slt | inst_sltu | inst_nor | inst_and | inst_or | inst_xor | 753 | inst_slli_w |inst_srli_w |inst_srai_w | inst_addi_w | inst_ld_w | inst_st_w | inst_jirl | inst_b | 754 | inst_bl | inst_beq | inst_bne | inst_lu12i_w | inst_slti | inst_sltui | inst_andi | inst_ori | 755 | inst_xori | inst_sll_w | inst_srl_w | inst_sra_w | inst_mul_w | inst_mulh_w | inst_mulh_wu | 756 | inst_div_w | inst_mod_w |inst_div_wu | inst_mod_wu | inst_blt | inst_bge | inst_bltu | 757 | inst_bgeu | inst_ld_b | inst_ld_h | inst_ld_bu | inst_ld_hu | inst_pcaddu12i | 758 | inst_st_b | inst_st_h | inst_csrrd | inst_csrwr | inst_csrxchg | inst_ertn | inst_syscall | 759 | inst_break | inst_rdcntid | inst_rdcntvh_w | inst_rdcntvl_w | 760 | inst_tlbsrch | inst_tlbrd | inst_tlbwr | inst_tlbfill | inst_invtlb); 761 | 762 | endmodule 763 | -------------------------------------------------------------------------------- /if_stage.v: -------------------------------------------------------------------------------- 1 | `include "mycpu.h" 2 | 3 | module if_stage#( 4 | parameter TLBNUM = 16 5 | ) 6 | ( 7 | input clk , 8 | input reset , 9 | //allwoin 10 | input ds_allowin , 11 | //brbus 12 | input [`BR_BUS_WD -1:0] br_bus , 13 | //to ds 14 | output fs_to_ds_valid , 15 | output [`FS_TO_DS_BUS_WD -1:0] fs_to_ds_bus , 16 | // inst sram interface 17 | output inst_sram_req , 18 | output [ 3:0] inst_sram_wstrb, 19 | output [ 31:0] inst_sram_addr , 20 | output [ 31:0] inst_sram_wdata, 21 | input [ 31:0] inst_sram_rdata, 22 | input [`WS_TO_FS_BUS_WD -1:0] ws_to_fs_bus, 23 | input [`ES_FORWARD_WD -1:0] es_forward, 24 | input [`MS_FORWARD_WD -1:0] ms_forward, 25 | input [`WS_FORWARD_WD -1:0] ws_forward, 26 | input back_ertn_flush, 27 | input back_ex, 28 | output [ 1:0] inst_sram_size,//0: 1bytes; 1: 2bytes; 2: 4bytes 29 | input inst_sram_addr_ok, 30 | input inst_sram_data_ok, 31 | output inst_sram_wr, 32 | input es_ex_detected_to_fs, 33 | input ms_ex_detected, 34 | // search port 0 (for fetch) 35 | output [ 18:0] s0_vppn, 36 | output s0_va_bit12, 37 | output [ 9:0] s0_asid, 38 | input s0_found, 39 | input [$clog2(TLBNUM)-1:0] s0_index, 40 | input [ 19:0] s0_ppn, 41 | input [ 5:0] s0_ps, 42 | input [ 1:0] s0_plv, 43 | input [ 1:0] s0_mat, 44 | input s0_d, 45 | input s0_v 46 | ); 47 | 48 | // Handshake signals 49 | reg fs_valid; 50 | wire fs_ready_go; 51 | wire fs_allowin; 52 | wire to_fs_valid; 53 | wire ps_ready_go; 54 | 55 | wire tlb_reflush; 56 | wire [31:0] refetch_pc; 57 | // PC 58 | wire [31:0] seq_pc; 59 | wire [31:0] nextpc; 60 | reg [31:0] fs_pc; 61 | wire [31:0] final_nextpc; 62 | // Ws to fs bus 63 | wire [31:0] ex_entry; 64 | wire final_ex; 65 | wire [31:0] ex_era; 66 | wire has_int; 67 | wire ertn_flush; 68 | 69 | wire fs_tlb_refetch; 70 | 71 | // Branch bus 72 | wire fs_ex_detected; 73 | wire br_taken; 74 | wire [ 31:0] br_target; 75 | wire br_stall; 76 | // Fs to ds bus 77 | wire [31:0] fs_inst; 78 | 79 | // Exception 80 | wire fs_esubcode; 81 | wire [ 5:0] fs_ecode; 82 | wire fs_ex; 83 | wire adef_ex; 84 | wire fs_tlb_refill_ex; 85 | wire fs_tlb_invalid_ex; 86 | wire fs_tlb_ppe_ex; 87 | wire refill_ex; 88 | // Handshake signals 89 | always @(posedge clk) begin 90 | if (reset) begin 91 | fs_valid <= 1'b0; 92 | end 93 | else if (fs_allowin) begin 94 | fs_valid <= to_fs_valid; 95 | end 96 | end 97 | 98 | /*-------------------- Address translation --------------------*/ 99 | wire [31:0] vaddr; 100 | wire [31:0] paddr; 101 | wire [19:0] vpn = vaddr[31:12]; 102 | wire [21:0] offset = vaddr[21:0]; 103 | 104 | wire dmw_hit = dmw0_hit || dmw1_hit; 105 | wire dmw0_hit; 106 | wire dmw1_hit; 107 | wire [31:0] dmw_addr; 108 | wire [31:0] tlb_addr; 109 | 110 | wire [31:0] csr_asid_rvalue; 111 | wire [31:0] csr_crmd_rvalue; 112 | wire [31:0] csr_dmw0_rvalue; 113 | wire [31:0] csr_dmw1_rvalue; 114 | wire [31:0] csr_tlbrentry_rvalue; 115 | 116 | wire csr_crmd_da = csr_crmd_rvalue[`CSR_CRMD_DA]; 117 | wire csr_crmd_pg = csr_crmd_rvalue[`CSR_CRMD_PG]; 118 | wire [1:0] csr_crmd_plv = csr_crmd_rvalue[`CSR_CRMD_PLV]; 119 | wire csr_dmw0_plv0 = csr_dmw0_rvalue[`CSR_DMW_PLV0]; 120 | wire csr_dmw0_plv3 = csr_dmw0_rvalue[`CSR_DMW_PLV3]; 121 | wire [2:0] csr_dmw0_vseg = csr_dmw0_rvalue[`CSR_DMW_VSEG]; 122 | wire [2:0] csr_dmw0_pseg = csr_dmw0_rvalue[`CSR_DMW_PSEG]; 123 | wire csr_dmw1_plv0 = csr_dmw1_rvalue[`CSR_DMW_PLV0]; 124 | wire csr_dmw1_plv3 = csr_dmw1_rvalue[`CSR_DMW_PLV3]; 125 | wire [2:0] csr_dmw1_vseg = csr_dmw1_rvalue[`CSR_DMW_VSEG]; 126 | wire [2:0] csr_dmw1_pseg = csr_dmw1_rvalue[`CSR_DMW_PSEG]; 127 | wire [9:0] csr_asid_asid = csr_asid_rvalue[`CSR_ASID_ASID]; 128 | 129 | 130 | // pre-IF stage 131 | // assign ps_ready_go = final_ex || ertn_flush || ~adef_ex; 132 | assign to_fs_valid = ~reset && ps_ready_go || fs_ex;//lab10 133 | 134 | // IF stage 135 | 136 | assign fs_ready_go = (inst_sram_data_ok || fs_inst_buf_valid) && ~final_ex && ~fs_abandon || fs_ex;//~cancel; //lab10 137 | assign fs_allowin = !fs_valid || fs_ready_go && ds_allowin || final_ex; 138 | assign fs_to_ds_valid = fs_valid && fs_ready_go && ~br_taken; 139 | 140 | // PC 141 | assign seq_pc = fs_pc + 32'h4; 142 | assign nextpc = refill_ex ? csr_tlbrentry_rvalue : 143 | final_ex & ~refill_ex ? (~ertn_flush ? ex_entry : ex_era) : 144 | (br_taken ? br_target : seq_pc); 145 | assign final_nextpc = refill_ex ? csr_tlbrentry_rvalue : 146 | tlb_reflush ? refetch_pc : 147 | final_ex & ~refill_ex? nextpc : 148 | (br_taken_buf | ex_buf_valid) ? nextpc_buf : 149 | nextpc; 150 | 151 | always @(posedge clk) begin 152 | if (reset) begin 153 | fs_pc <= 32'h1bfffffc; //trick: to make nextpc be 0x1c000000 during reset 154 | end 155 | else if (to_fs_valid && fs_allowin) begin 156 | fs_pc <= final_nextpc; 157 | end 158 | end 159 | 160 | /* ------------------- lab 10 ------------------- */ 161 | assign ps_ready_go = inst_sram_req && inst_sram_addr_ok;//????fs_ex 162 | 163 | reg [31:0] fs_inst_buf; 164 | reg fs_inst_buf_valid; 165 | reg br_taken_buf; 166 | reg [31:0] nextpc_buf; 167 | reg ex_buf_valid; 168 | reg fs_abandon; 169 | reg mid_handshake; 170 | 171 | always @(posedge clk) begin 172 | if(reset) begin 173 | fs_inst_buf <= 32'b0; 174 | end 175 | else if(inst_sram_data_ok && ~ds_allowin) begin 176 | fs_inst_buf <= inst_sram_rdata; 177 | end 178 | end 179 | 180 | always @(posedge clk) begin 181 | if(reset) begin 182 | fs_inst_buf_valid <= 1'b0; 183 | end 184 | else if(fs_ready_go && ds_allowin || final_ex) begin 185 | fs_inst_buf_valid <= 1'b0; 186 | end 187 | else if(inst_sram_data_ok && ~ds_allowin) begin 188 | fs_inst_buf_valid <= 1'b1; 189 | end 190 | end 191 | 192 | always @(posedge clk)begin 193 | if(reset) begin 194 | br_taken_buf <= 1'b0; 195 | end 196 | else if(br_taken_buf && inst_sram_req && inst_sram_addr_ok && fs_allowin) begin 197 | br_taken_buf <= 1'b0; 198 | end 199 | else if(br_taken && ~br_stall && ~(inst_sram_req && inst_sram_addr_ok)) begin 200 | br_taken_buf <= br_taken; 201 | end 202 | end 203 | 204 | always @(posedge clk) begin 205 | if(reset) begin 206 | ex_buf_valid <= 1'b0; 207 | end 208 | else if(ex_buf_valid && inst_sram_req && inst_sram_addr_ok && fs_allowin) begin 209 | ex_buf_valid <= 1'b0; 210 | end 211 | else if(final_ex && ~(inst_sram_req && inst_sram_addr_ok)) begin 212 | ex_buf_valid <= 1'b1; 213 | end 214 | end 215 | 216 | always @(posedge clk) begin 217 | if(reset) begin 218 | nextpc_buf <= 32'b0; 219 | end 220 | else if(br_taken && ~br_stall || final_ex) begin 221 | nextpc_buf <= nextpc; 222 | end 223 | end 224 | 225 | always @(posedge clk) begin 226 | if(reset) begin 227 | fs_abandon <= 1'b0; 228 | end 229 | else if(inst_sram_data_ok) begin 230 | fs_abandon <= 1'b0; 231 | end 232 | else if(final_ex && (~fs_allowin && ~fs_ready_go)) begin 233 | fs_abandon <= 1'b1; 234 | end 235 | end 236 | 237 | assign inst_sram_size = 2'b10; 238 | // Sram interface 239 | assign inst_sram_req = fs_allowin && ~fs_ex && ~br_stall && ~mid_handshake 240 | && ~fs_ex_detected && ~es_ex_detected_to_fs && ~ms_ex_detected; //req 241 | assign inst_sram_wstrb = 4'h0; //wstrb 242 | assign inst_sram_addr = paddr; 243 | assign inst_sram_wdata = 32'b0; 244 | assign inst_sram_wr = 1'b0; 245 | // Exception 246 | assign fs_esubcode = adef_ex ? `ESUBCODE_ADEF : 1'b0; 247 | assign fs_ecode = adef_ex ? `ECODE_ADE : 248 | fs_tlb_refill_ex ? `ECODE_TLBR : 249 | fs_tlb_invalid_ex ? `ECODE_PIF : 250 | fs_tlb_ppe_ex ? `ECODE_PPE : 6'b0; 251 | assign fs_ex = adef_ex | fs_tlb_invalid_ex | fs_tlb_ppe_ex | fs_tlb_refill_ex; 252 | assign adef_ex = ~(final_nextpc[1:0] == 2'b00 && final_nextpc[31] == 1'b0); 253 | 254 | 255 | // Waiting for response state 256 | // This state will occur after first handshake occurs 257 | // and will disappear when second handshake arrives 258 | 259 | always @(posedge clk) begin 260 | if (reset) 261 | mid_handshake <= 1'b0; 262 | else if (inst_sram_data_ok) 263 | mid_handshake <= 1'b0; 264 | else if (inst_sram_req && inst_sram_addr_ok) 265 | mid_handshake <= 1'b1; 266 | end 267 | 268 | assign {refill_ex, //260 269 | csr_tlbrentry_rvalue, //259:228 270 | csr_asid_rvalue, //227:196 271 | csr_crmd_rvalue, //195:164 272 | csr_dmw0_rvalue, //163:132 273 | csr_dmw1_rvalue, //131:100 274 | tlb_reflush,//99 275 | refetch_pc,//98:67 276 | has_int, //66 277 | ex_era, //65:34 278 | ex_entry, //33:2 279 | final_ex, //1 280 | ertn_flush //0 281 | } = ws_to_fs_bus; 282 | 283 | assign {fs_tlb_refetch, fs_ex_detected, br_stall,br_taken,br_target} = br_bus; 284 | 285 | assign fs_inst = fs_ex ? {11'b0, 1'b1, 20'b0} : 286 | fs_inst_buf_valid ? fs_inst_buf : inst_sram_rdata; 287 | 288 | assign fs_to_ds_bus = {fs_tlb_refill_ex,//73 289 | fs_tlb_refetch,//72 290 | fs_esubcode , //71 291 | fs_ecode , //70:65 292 | fs_ex , //64 293 | fs_inst , //63:32 294 | fs_pc //31:0 295 | }; 296 | 297 | /*-------------------- Address translation --------------------*/ 298 | assign vaddr = final_nextpc; 299 | 300 | // TLB 301 | assign s0_vppn = vpn[19:1]; 302 | assign s0_va_bit12 = vpn[0]; 303 | assign s0_asid = csr_asid_asid; 304 | 305 | assign tlb_addr = (s0_ps == 6'd12) ? {s0_ppn[19:0], offset[11:0]} : 306 | {s0_ppn[19:10], offset[21:0]}; 307 | 308 | 309 | assign da_hit = (csr_crmd_da == 1) && (csr_crmd_pg == 0); 310 | 311 | // DMW 312 | assign dmw0_hit = (csr_crmd_plv == 2'b00 && csr_dmw0_plv0 || 313 | csr_crmd_plv == 2'b11 && csr_dmw0_plv3 ) && (vaddr[31:29] == csr_dmw0_vseg); 314 | assign dmw1_hit = (csr_crmd_plv == 2'b00 && csr_dmw1_plv0 || 315 | csr_crmd_plv == 2'b11 && csr_dmw1_plv3 ) && (vaddr[31:29] == csr_dmw1_vseg); 316 | 317 | assign dmw_addr = {32{dmw0_hit}} & {csr_dmw0_vseg, vaddr[28:0]} | 318 | {32{dmw1_hit}} & {csr_dmw1_vseg, vaddr[28:0]}; 319 | 320 | // PADDR 321 | assign paddr = da_hit ? vaddr : 322 | dmw_hit ? dmw_addr : 323 | tlb_addr; 324 | 325 | assign fs_tlb_refill_ex = ~da_hit & ~dmw_hit & ~s0_found; 326 | assign fs_tlb_invalid_ex = ~da_hit & ~dmw_hit & s0_found & ~s0_v; 327 | assign fs_tlb_ppe_ex = ~da_hit & ~dmw_hit & csr_crmd_plv == 2'b11 && s0_plv == 2'b00; 328 | 329 | endmodule 330 | -------------------------------------------------------------------------------- /mem_stage.v: -------------------------------------------------------------------------------- 1 | `include "mycpu.h" 2 | 3 | module mem_stage( 4 | input clk , 5 | input reset , 6 | input final_ex , 7 | //allowin 8 | input ws_allowin , 9 | output ms_allowin , 10 | //from es 11 | input es_to_ms_valid, 12 | input [`ES_TO_MS_BUS_WD -1:0] es_to_ms_bus , 13 | //to ws 14 | output ms_to_ws_valid, 15 | output [`MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus , 16 | //from data-sram 17 | input [31 :0] data_sram_rdata, 18 | input data_sram_data_ok, 19 | 20 | output [`MS_FORWARD_WD -1:0] ms_forward , 21 | input back_ertn_flush, 22 | output ms_ertn_flush , 23 | output ms_to_es_valid, 24 | input back_ex , 25 | output ms_to_es_ex , 26 | output ms_ex_detected 27 | ); 28 | 29 | /* -------------- Handshaking signals -------------- */ 30 | 31 | reg ms_valid; 32 | wire ms_ready_go; 33 | 34 | 35 | 36 | /* ------------------- BUS ------------------- */ 37 | 38 | // ES to MS bus 39 | reg [`ES_TO_MS_BUS_WD -1:0] es_to_ms_bus_r; 40 | 41 | wire ms_tlb_refetch; 42 | wire es_mem_ex; 43 | 44 | /* -------------- MEM related -------------- */ 45 | wire ms_op_st_w; 46 | wire ms_op_ld_w; 47 | wire ms_op_ld_b; 48 | wire ms_op_ld_bu; 49 | wire ms_op_ld_h; 50 | wire ms_op_ld_hu; 51 | wire ms_op_st_b; 52 | wire ms_op_st_h; 53 | wire ms_op_mem = ms_op_st_w || ms_op_st_h || ms_op_st_b || ms_op_ld_w || ms_op_ld_hu || ms_op_ld_h || ms_op_ld_bu || ms_op_ld_b; 54 | 55 | wire ms_res_from_mem; 56 | wire ms_gr_we; 57 | wire [ 4:0] ms_dest; 58 | wire [31:0] ms_alu_result; 59 | wire [31:0] ms_pc; 60 | 61 | wire [1:0] ms_addr_lowbits; 62 | wire addr00; 63 | wire addr01; 64 | wire addr10; 65 | wire addr11; 66 | wire [7:0] mem_byte_data; 67 | wire [15:0] mem_halfword_data; 68 | wire [31:0] mem_result; 69 | wire [31:0] ms_final_result; 70 | wire [31:0] badvaddr; 71 | 72 | 73 | /* -------------- CSR instructions -------------- */ 74 | wire [13:0] ms_csr_num; 75 | wire ms_csr_re; 76 | wire [31:0] ms_csr_wmask; 77 | wire [31:0] ms_csr_wvalue; 78 | wire ms_csr_we; 79 | 80 | wire ms_csr_block; 81 | 82 | wire inst_tlbsrch; 83 | wire inst_tlbrd; 84 | wire inst_tlbwr; 85 | wire inst_tlbfill; 86 | wire inst_invtlb; 87 | /* -------------- Exceptions -------------- */ 88 | 89 | wire ms_inst_rdcntid; 90 | 91 | wire ms_ertn_flush; 92 | wire ms_esubcode; 93 | wire [ 5:0] ms_ecode; 94 | wire ms_ex; 95 | wire ms_ale_ex; 96 | 97 | wire es_tlb_refill_ex; 98 | /* -------------- Abandon -------------- */ 99 | reg ms_abandon; 100 | 101 | /* -------------- Handshaking signals -------------- */ 102 | assign ms_ready_go = ms_op_mem ? (data_sram_data_ok || data_sram_rdata_buf_valid) && ~ms_abandon || es_mem_ex : 1'b1; 103 | assign ms_allowin = !ms_valid || ms_ready_go && ws_allowin; 104 | assign ms_to_ws_valid = ms_valid && ms_ready_go; 105 | 106 | always @(posedge clk) begin 107 | if (reset | final_ex | back_ertn_flush ) begin 108 | ms_valid <= 1'b0; 109 | end 110 | else if (ms_allowin) begin 111 | ms_valid <= es_to_ms_valid; 112 | end 113 | end 114 | 115 | /* ------------------- BUS ------------------- */ 116 | 117 | always @(posedge clk) begin 118 | if (es_to_ms_valid && ms_allowin) begin 119 | es_to_ms_bus_r <= es_to_ms_bus; 120 | end 121 | end 122 | 123 | assign {badvaddr , //210:179 124 | es_mem_ex , //178 125 | es_tlb_refill_ex, //177 126 | ms_tlb_refetch , //176 127 | inst_tlbsrch , //175 128 | inst_tlbrd , //174 129 | inst_tlbwr , //173 130 | inst_tlbfill , //172 131 | inst_invtlb , //171 132 | ms_op_st_w , //170 133 | ms_inst_rdcntid, //169 134 | ms_ertn_flush , //168 135 | ms_esubcode , //167 136 | ms_ecode , //166:161 137 | ms_ex , //160 138 | ms_csr_re , //159 139 | ms_csr_num , //158:145 140 | ms_csr_wvalue , //144:113 141 | ms_csr_wmask , //112:81 142 | ms_csr_we , //80 143 | ms_addr_lowbits, //79:78 144 | ms_op_ld_w , //77 145 | ms_op_ld_b , //76 146 | ms_op_ld_bu , //75 147 | ms_op_ld_h , //74 148 | ms_op_ld_hu , //73 149 | ms_op_st_b , //72 150 | ms_op_st_h , //71 151 | ms_res_from_mem, //70:70 152 | ms_gr_we , //69:69 153 | ms_dest , //68:64 154 | ms_alu_result , //63:32 155 | ms_pc //31:0 156 | } = es_to_ms_bus_r; 157 | 158 | // MS to WS bus 159 | assign ms_to_ws_bus = {es_tlb_refill_ex, //198 160 | ms_tlb_refetch , //197 161 | inst_tlbsrch , //196 162 | inst_tlbrd , //195 163 | inst_tlbwr , //194 164 | inst_tlbfill , //193 165 | inst_invtlb , //192 166 | ms_inst_rdcntid, //191 167 | badvaddr , //190:159 168 | ms_ertn_flush , //158 169 | ms_esubcode , //157 170 | ms_ecode , //156:151 171 | ms_ex , //150 172 | ms_csr_re , //149 173 | ms_csr_num , //148:135 174 | ms_csr_wvalue , //134:103 175 | ms_csr_wmask , //102:71 176 | ms_csr_we , //70 177 | ms_gr_we , //69:69 178 | ms_dest , //68:64 179 | ms_final_result, //63:32 180 | ms_pc //31:0 181 | }; 182 | 183 | // MS forward bus 184 | assign ms_forward = {ms_res_from_mem, //59 185 | data_sram_data_ok,//58 186 | ms_csr_block,//57 187 | ms_csr_re, //56 188 | ms_csr_num, //55:42 189 | ms_csr_we, //41 190 | ms_ertn_flush, //40 191 | ms_ex && ms_to_ws_valid, //39 192 | ms_final_result, //38:7 193 | ms_dest , //6:2 194 | ms_gr_we, //1:1 195 | ms_valid //0:0 196 | }; 197 | 198 | 199 | 200 | /* -------------- MEM read interface -------------- */ 201 | 202 | 203 | // SRAM data buffer 204 | reg [32:0] data_sram_rdata_buf; 205 | reg data_sram_rdata_buf_valid; 206 | wire [32:0] final_data_sram_rdata; 207 | 208 | always @(posedge clk) begin 209 | if (reset) 210 | data_sram_rdata_buf <= 32'b0; 211 | else if (data_sram_data_ok && ~ws_allowin) // If data is back, WB stage do not allow in 212 | // Then write it into buffer, wait for allowin to rise 213 | data_sram_rdata_buf <= data_sram_rdata; 214 | end 215 | 216 | always @(posedge clk) begin 217 | if (reset) 218 | data_sram_rdata_buf_valid <= 1'b0; 219 | else if (data_sram_data_ok && ~ws_allowin) 220 | data_sram_rdata_buf_valid <= 1'b1; 221 | else if (ms_ready_go && ws_allowin) 222 | data_sram_rdata_buf_valid <= 1'b0; 223 | end 224 | 225 | assign final_data_sram_rdata = data_sram_rdata_buf_valid ? data_sram_rdata_buf : data_sram_rdata; 226 | 227 | // mem_byte_data mux 228 | assign addr00 = ms_addr_lowbits == 2'b00; 229 | assign addr01 = ms_addr_lowbits == 2'b01; 230 | assign addr10 = ms_addr_lowbits == 2'b10; 231 | assign addr11 = ms_addr_lowbits == 2'b11; 232 | assign mem_byte_data = {8{addr00}} & final_data_sram_rdata[7:0] | 233 | {8{addr01}} & final_data_sram_rdata[15:8] | 234 | {8{addr10}} & final_data_sram_rdata[23:16] | 235 | {8{addr11}} & final_data_sram_rdata[31:24]; 236 | 237 | // mem_halfword_data mux 238 | assign mem_halfword_data = {16{addr00}} & final_data_sram_rdata[15:0] | 239 | {16{addr10}} & final_data_sram_rdata[31:16]; 240 | // mem_result mux 241 | assign mem_result = {32{ms_op_ld_w}} & final_data_sram_rdata | 242 | {32{ms_op_ld_b}} & {{24{mem_byte_data[7]}}, mem_byte_data} | 243 | {32{ms_op_ld_bu}} & {24'b0, mem_byte_data} | 244 | {32{ms_op_ld_h}} & {{16{mem_halfword_data[15]}}, mem_halfword_data}| 245 | {32{ms_op_ld_hu}} & {16'b0, mem_halfword_data}; 246 | 247 | 248 | assign ms_final_result = ms_res_from_mem ? mem_result : ms_alu_result; 249 | 250 | 251 | 252 | /* -------------- Abandon -------------- */ 253 | always @(posedge clk) begin 254 | if (reset) 255 | ms_abandon <= 1'b0; 256 | else if (ms_op_mem && data_sram_data_ok) 257 | ms_abandon <= 1'b0; 258 | else if (ms_op_mem && final_ex && (es_to_ms_valid || ~ws_allowin && ~ms_ready_go)) 259 | ms_abandon <= 1'b1; 260 | end 261 | 262 | /* -------------- CSR instructions -------------- */ 263 | 264 | assign ms_csr_block = ms_valid & ms_csr_re; 265 | 266 | assign ms_to_es_valid = ms_valid; 267 | 268 | 269 | assign ms_ale_ex = ms_ecode == `ECODE_ALE; 270 | 271 | 272 | assign ms_to_es_ex = ms_ex; 273 | assign ms_ex_detected = ms_ex && ms_valid; 274 | 275 | endmodule 276 | -------------------------------------------------------------------------------- /mycpu.h: -------------------------------------------------------------------------------- 1 | `ifndef MYCPU_H 2 | `define MYCPU_H 3 | 4 | // Bus width 5 | `define BR_BUS_WD 36 6 | `define FS_TO_DS_BUS_WD 74 7 | `define DS_TO_ES_BUS_WD 269 8 | `define ES_TO_MS_BUS_WD 211 9 | `define MS_TO_WS_BUS_WD 199 10 | `define WS_TO_RF_BUS_WD 38 11 | `define WS_TO_FS_BUS_WD 261 12 | `define ES_FORWARD_WD 59 13 | `define MS_FORWARD_WD 60 14 | `define WS_FORWARD_WD 124 15 | `define WS_TO_ES_BUS_WD 160 16 | // CSR 17 | // CRMD 18 | `define CSR_CRMD 0 19 | `define CSR_CRMD_PLV 1:0 20 | `define CSR_CRMD_IE 2 21 | `define CSR_CRMD_DA 3 22 | `define CSR_CRMD_PG 4 23 | `define CSR_CRMD_DATF 6:5 24 | `define CSR_CRMD_DATM 8:7 25 | // PRMD 26 | `define CSR_PRMD 1 27 | `define CSR_PRMD_PPLV 1:0 28 | `define CSR_PRMD_PIE 2 29 | // ECFG 30 | `define CSR_ECFG 4 31 | `define CSR_ECFG_LIE 12:0 32 | // ESTAT 33 | `define CSR_ESTAT 5 34 | `define CSR_ESTAT_IS10 1:0 35 | // ERA 36 | `define CSR_ERA 6 37 | `define CSR_ERA_PC 31:0 38 | // EENTRY 39 | `define CSR_EENTRY 12 40 | `define CSR_EENTRY_VA 31:6 41 | // SAVE 42 | `define CSR_SAVE0 48 43 | `define CSR_SAVE1 49 44 | `define CSR_SAVE2 50 45 | `define CSR_SAVE3 51 46 | `define CSR_SAVE_DATA 31:0 47 | // BADV 48 | `define CSR_BADV 7 49 | `define CSR_BADV_VADDR 31:0 50 | // TID 51 | `define CSR_TID 64 52 | `define CSR_TID_TID 31:0 53 | // TCFG 54 | `define CSR_TCFG 65 55 | `define CSR_TCFG_EN 0 56 | `define CSR_TCFG_PERIODIC 1 57 | `define CSR_TCFG_INITVAL 31:2 58 | // TVAL 59 | `define CSR_TVAL 66 60 | `define CSR_TVAL_TIMEVAL 63:0 61 | // TICLR 62 | `define CSR_TICLR 68 63 | `define CSR_TICLR_CLR 0 64 | // TLBIDX 65 | `define CSR_TLBIDX 16 66 | `define CSR_TLBIDX_INDEX 4 :0 67 | `define CSR_TLBIDX_PS 29:24 68 | `define CSR_TLBIDX_NE 31 69 | // TLBEHI 70 | `define CSR_TLBEHI 17 71 | `define CSR_TLBEHI_VPPN 31:13 72 | // TLBELO0 // TLBELO1 73 | `define CSR_TLBELO0 18 74 | `define CSR_TLBELO1 19 75 | `define CSR_TLBELO_V 0 76 | `define CSR_TLBELO_D 1 77 | `define CSR_TLBELO_PLV 3 :2 78 | `define CSR_TLBELO_MAT 5 :4 79 | `define CSR_TLBELO_G 6 80 | `define CSR_TLBELO_PPN 31:8 81 | // ASID 82 | `define CSR_ASID 24 83 | `define CSR_ASID_ASID 9 :0 84 | `define CSR_ASID_ASIDBITS 23:16 85 | // TLBRENTRY 86 | `define CSR_TLBRENTRY 136 87 | `define CSR_TLBRENTRY_PA 31:6 88 | // DMW 89 | `define CSR_DMW0 384 90 | `define CSR_DMW1 385 91 | `define CSR_DMW_VSEG 31:29 92 | `define CSR_DMW_PSEG 27:25 93 | `define CSR_DMW_MAT 5:4 94 | `define CSR_DMW_PLV3 3 95 | `define CSR_DMW_PLV0 0 96 | // ECODE 97 | `define ECODE_ADE 8 98 | `define ECODE_ALE 9 99 | `define ECODE_SYS 11 100 | `define ECODE_BRK 12 101 | `define ECODE_INE 13 102 | `define ECODE_INT 0 103 | `define ECODE_ERT 15 104 | `define ECODE_PIL 1 105 | `define ECODE_PIS 2 106 | `define ECODE_PIF 3 107 | `define ECODE_PME 4 108 | `define ECODE_PPE 7 109 | `define ECODE_TLBR 63 110 | `define ESUBCODE_ADEF 0 111 | `endif 112 | -------------------------------------------------------------------------------- /mycpu_top.v: -------------------------------------------------------------------------------- 1 | module mycpu_top( 2 | input aclk, 3 | input aresetn, 4 | 5 | // AXI bridge interface 6 | // read request channel 7 | output [ 3:0] arid,//inst: 0,data: 1 8 | output [31:0] araddr, 9 | output [ 7:0] arlen,//0 10 | output [ 2:0] arsize, 11 | output [ 1:0] arburst,//0b01 12 | output [ 1:0] arlock,//0 13 | output [ 3:0] arcache,//0 14 | output [ 2:0] arprot,//0 15 | output arvalid,//read address valid 16 | input arready,//read address valid 17 | // read respond channel 18 | input [ 3:0] rid, 19 | input [31:0] rdata, 20 | input [ 1:0] rresp,//ignore 21 | input rlast,//ignore 22 | input rvalid,//read valid 23 | output rready,//read ready 24 | // write request channel 25 | output [ 3:0] awid,//1 26 | output [31:0] awaddr, 27 | output [ 7:0] awlen,//0 28 | output [ 2:0] awsize, 29 | output [ 1:0] awburst,//0b01 30 | output [ 1:0] awlock,//0 31 | output [ 3:0] awcache,//0 32 | output [ 2:0] awprot,//0 33 | output awvalid,//write address valid 34 | input awready,//write address valid 35 | // write data channel 36 | output [ 3:0] wid,//1 37 | output [31:0] wdata, 38 | output [ 3:0] wstrb,//WSTRB[n] corresponds to WDATA[(8n) + 7: (8n)]. 39 | output wlast,//1 40 | output wvalid, 41 | input wready, 42 | // write respond channel 43 | input [ 3:0] bid,//ignore 44 | input [ 1:0] bresp,//ignore 45 | input bvalid,//write response valid 46 | output bready,//write response ready 47 | 48 | // trace debug interface 49 | output [31:0] debug_wb_pc, 50 | output [ 3:0] debug_wb_rf_wen, 51 | output [ 4:0] debug_wb_rf_wnum, 52 | output [31:0] debug_wb_rf_wdata 53 | ); 54 | 55 | wire clk; 56 | wire resetn; 57 | assign clk = aclk; 58 | assign resetn = aresetn; 59 | 60 | wire inst_sram_req; 61 | wire [ 3:0] inst_sram_wstrb; 62 | wire [31:0] inst_sram_addr; 63 | wire [31:0] inst_sram_wdata; 64 | wire [31:0] inst_sram_rdata; 65 | wire [ 1:0] inst_sram_size; 66 | wire inst_sram_addr_ok; 67 | wire inst_sram_data_ok; 68 | wire inst_sram_wr; 69 | 70 | wire data_sram_req; 71 | wire [ 3:0] data_sram_wstrb; 72 | wire [31:0] data_sram_addr; 73 | wire [31:0] data_sram_wdata; 74 | wire [31:0] data_sram_rdata; 75 | wire [ 1:0] data_sram_size; 76 | wire data_sram_addr_ok; 77 | wire data_sram_data_ok; 78 | wire data_sram_wr; 79 | 80 | axi_bridge axi_bridge( 81 | .aclk (aclk ), 82 | .aresetn (aresetn ), 83 | // read request 84 | .arid (arid ), 85 | .araddr (araddr ), 86 | .arlen (arlen ), 87 | .arsize (arsize ), 88 | .arburst (arburst ), 89 | .arlock (arlock ), 90 | .arcache (arcache ), 91 | .arprot (arprot ), 92 | .arvalid (arvalid ), 93 | .arready (arready ), 94 | // read respond 95 | .rid (rid ), 96 | .rdata (rdata ), 97 | .rresp (rresp ), 98 | .rvalid (rvalid ), 99 | .rready (rready ), 100 | // write request 101 | .awid (awid ), 102 | .awaddr (awaddr ), 103 | .awlen (awlen ), 104 | .awsize (awsize ), 105 | .awburst (awburst ), 106 | .awlock (awlock ), 107 | .awcache (awcache ), 108 | .awprot (awprot ), 109 | .awvalid (awvalid ), 110 | .awready (awready ), 111 | // write data 112 | .wid (wid ), 113 | .wdata (wdata ), 114 | .wstrb (wstrb ), 115 | .wlast (wlast ), 116 | .wvalid (wvalid ), 117 | .wready (wready ), 118 | // write respond 119 | .bid (bid ), 120 | .bresp (bresp ), 121 | .bvalid (bvalid ), 122 | .bready (bready ), 123 | 124 | // inst sram interface 125 | .inst_sram_req (inst_sram_req ), 126 | .inst_sram_wstrb (inst_sram_wstrb ), 127 | .inst_sram_addr (inst_sram_addr ), 128 | .inst_sram_wdata (inst_sram_wdata ), 129 | .inst_sram_rdata (inst_sram_rdata ), 130 | .inst_sram_size (inst_sram_size ), 131 | .inst_sram_addr_ok (inst_sram_addr_ok), 132 | .inst_sram_data_ok (inst_sram_data_ok), 133 | .inst_sram_wr (inst_sram_wr ), 134 | // data sram interface 135 | .data_sram_req (data_sram_req ), 136 | .data_sram_wstrb (data_sram_wstrb ), 137 | .data_sram_addr (data_sram_addr ), 138 | .data_sram_wdata (data_sram_wdata ), 139 | .data_sram_rdata (data_sram_rdata ), 140 | .data_sram_size (data_sram_size ), 141 | .data_sram_addr_ok (data_sram_addr_ok), 142 | .data_sram_data_ok (data_sram_data_ok), 143 | .data_sram_wr (data_sram_wr ) 144 | ); 145 | 146 | 147 | 148 | cpu_core cpu_core( 149 | .clk (clk ), 150 | .resetn (resetn ), 151 | // inst sram interface 152 | .inst_sram_req (inst_sram_req ), 153 | .inst_sram_wstrb (inst_sram_wstrb ), 154 | .inst_sram_addr (inst_sram_addr ), 155 | .inst_sram_wdata (inst_sram_wdata ), 156 | .inst_sram_rdata (inst_sram_rdata ), 157 | .inst_sram_size (inst_sram_size ), 158 | .inst_sram_addr_ok (inst_sram_addr_ok), 159 | .inst_sram_data_ok (inst_sram_data_ok), 160 | .inst_sram_wr (inst_sram_wr ), 161 | // data sram interface 162 | .data_sram_req (data_sram_req ), 163 | .data_sram_wstrb (data_sram_wstrb ), 164 | .data_sram_addr (data_sram_addr ), 165 | .data_sram_wdata (data_sram_wdata ), 166 | .data_sram_rdata (data_sram_rdata ), 167 | .data_sram_size (data_sram_size ), 168 | .data_sram_addr_ok (data_sram_addr_ok), 169 | .data_sram_data_ok (data_sram_data_ok), 170 | .data_sram_wr (data_sram_wr ), 171 | // trace debug interface 172 | .debug_wb_pc (debug_wb_pc ), 173 | .debug_wb_rf_wen (debug_wb_rf_wen ), 174 | .debug_wb_rf_wnum (debug_wb_rf_wnum ), 175 | .debug_wb_rf_wdata (debug_wb_rf_wdata) 176 | ); 177 | 178 | 179 | 180 | endmodule 181 | -------------------------------------------------------------------------------- /regcsr.v: -------------------------------------------------------------------------------- 1 | `include "mycpu.h" 2 | 3 | module regcsr( 4 | input clk , 5 | input reset , 6 | input ws_valid , 7 | input csr_we , //写使�?? 8 | input [13:0] csr_num , //寄存器号 9 | input [31:0] csr_wmask , //写掩�?? 10 | input [31:0] csr_wvalue, //写数�?? 11 | output [31:0] csr_rvalue, //读返回�?? 12 | 13 | input ertn_flush, //ertn执行有效信号 14 | input wb_ex , //写回流水级异�?? 15 | input refill_ex , 16 | input [ 5:0] wb_ecode , //异常类型 17 | input wb_esubcode,// 18 | input [31:0] wb_pc , //!!!! 19 | input [31:0] wb_vaddr , //访存虚地�?? 20 | 21 | output [31:0] ex_entry , //to pre-IF, 异常处理入口地址 22 | output [31:0] ex_era , 23 | output has_int , //to id, 中断有效信号 24 | // counter 25 | output [63:0] counter , 26 | output [31:0] counter_id, 27 | // tlb 28 | input [97:0] csr_tlb_in, 29 | output [97:0] csr_tlb_out, 30 | output [31:0] csr_asid_rvalue, 31 | output [31:0] csr_tlbehi_rvalue, 32 | output [31:0] csr_crmd_rvalue, 33 | output [31:0] csr_dmw0_rvalue, 34 | output [31:0] csr_dmw1_rvalue, 35 | output [31:0] csr_tlbrentry_rvalue 36 | ); 37 | //wire es_valid; 38 | wire inst_tlbfill; 39 | wire inst_tlbsrch; 40 | wire inst_tlbrd; 41 | wire s1_found; 42 | wire [ 3:0] s1_index; 43 | wire we; 44 | wire [ 3:0] w_index; 45 | wire w_e; 46 | wire [18:0] w_vppn; 47 | wire [ 5:0] w_ps; 48 | wire [ 9:0] w_asid; 49 | wire w_g; 50 | wire [19:0] w_ppn0; 51 | wire [ 1:0] w_plv0; 52 | wire [ 1:0] w_mat0; 53 | wire w_d0; 54 | wire w_v0; 55 | wire [19:0] w_ppn1; 56 | wire [ 1:0] w_plv1; 57 | wire [ 1:0] w_mat1; 58 | wire w_d1; 59 | wire w_v1; 60 | wire [ 3:0] r_index; 61 | wire r_e; 62 | wire [18:0] r_vppn; 63 | wire [ 5:0] r_ps; 64 | wire [ 9:0] r_asid; 65 | wire r_g; 66 | wire [19:0] r_ppn0; 67 | wire [ 1:0] r_plv0; 68 | wire [ 1:0] r_mat0; 69 | wire r_d0; 70 | wire r_v0; 71 | wire [19:0] r_ppn1; 72 | wire [ 1:0] r_plv1; 73 | wire [ 1:0] r_mat1; 74 | wire r_d1; 75 | wire r_v1; 76 | 77 | assign {//es_valid, //96 78 | inst_tlbwr,//97 79 | inst_tlbfill,//96 80 | inst_tlbsrch,//95 81 | inst_tlbrd, //94 82 | s1_found, //93 83 | s1_index, //92:89 84 | r_e, //88 85 | r_vppn, //87:69 86 | r_ps, //68:63 87 | r_asid, //62:53 88 | r_g, //52 89 | r_ppn0, //51:32 90 | r_plv0, //31:30 91 | r_mat0, //29:28 92 | r_d0, //27 93 | r_v0, //26 94 | r_ppn1, //25:6 95 | r_plv1, //5:4 96 | r_mat1, //3:2 97 | r_d1, //1 98 | r_v1 //0 99 | } = csr_tlb_in ; 100 | 101 | assign csr_tlb_out = {we, //97 102 | w_index,//96:93 103 | w_e, //92 104 | w_vppn, //91:73 105 | w_ps, //72:67 106 | w_asid, //66:57 107 | w_g, //56 108 | w_ppn0, //55:36 109 | w_plv0, //35:34 110 | w_mat0, //33:32 111 | w_d0, //31 112 | w_v0, //30 113 | w_ppn1, //29:10 114 | w_plv1, //9:8 115 | w_mat1, //7:6 116 | w_d1, //5 117 | w_v1, //4 118 | r_index //3:0 119 | }; 120 | 121 | reg [ 1:0] csr_crmd_plv; //priority level 122 | reg csr_crmd_ie; //interrupt enable 123 | reg csr_crmd_da; //direct address enable 124 | reg csr_crmd_pg; //mapping address enable 125 | reg [ 1:0] csr_crmd_datf; //in direct address 126 | reg [ 1:0] csr_crmd_datm; //in direct address 127 | reg [ 1:0] csr_prmd_pplv; 128 | reg csr_prmd_pie; 129 | reg [12:0] csr_ecfg_lie; 130 | reg [12:0] csr_estat_is; 131 | reg [ 5:0] csr_estat_ecode; 132 | reg [ 8:0] csr_estat_esubcode; 133 | reg [31:0] csr_era_pc; 134 | reg [25:0] csr_eentry_va; 135 | reg [31:0] csr_save0_data; 136 | reg [31:0] csr_save1_data; 137 | reg [31:0] csr_save2_data; 138 | reg [31:0] csr_save3_data; 139 | 140 | // Add in lab 9 141 | reg [31:0] csr_badv_vaddr; 142 | reg [31:0] csr_tid_tid; 143 | reg csr_tcfg_en; 144 | reg csr_tcfg_periodic; 145 | reg [29:0] csr_tcfg_initval; 146 | wire [31:0] tcfg_next_value; 147 | wire [31:0] csr_tval; 148 | reg [31:0] timer_cnt; 149 | wire csr_ticlr_clr; 150 | wire wb_ex_addr_err; 151 | 152 | // Add in lab 14 153 | 154 | // TLBIDX 155 | reg [ 3:0] csr_tlbidx_index; 156 | reg [ 5:0] csr_tlbidx_ps; 157 | reg csr_tlbidx_ne; 158 | 159 | // TLBEHI 160 | reg [18:0] csr_tlbehi_vppn; 161 | 162 | // TLBELO 163 | reg csr_tlbelo0_v; 164 | reg csr_tlbelo0_d; 165 | reg [ 1:0] csr_tlbelo0_plv; 166 | reg [ 1:0] csr_tlbelo0_mat; 167 | reg csr_tlbelo0_g; 168 | reg [23:0] csr_tlbelo0_ppn; 169 | reg csr_tlbelo1_v; 170 | reg csr_tlbelo1_d; 171 | reg [ 1:0] csr_tlbelo1_plv; 172 | reg [ 1:0] csr_tlbelo1_mat; 173 | reg csr_tlbelo1_g; 174 | reg [23:0] csr_tlbelo1_ppn; 175 | 176 | // ASID 177 | reg [ 9:0] csr_asid_asid; 178 | wire [ 7:0] csr_asid_asidbits = 8'd10; 179 | 180 | // TLBRENTRY 181 | reg [25:0] csr_tlbrentry_pa; 182 | 183 | // DMW 184 | reg csr_dmw0_plv0; 185 | reg csr_dmw0_plv3; 186 | reg [ 1:0] csr_dmw0_mat; 187 | reg [ 2:0] csr_dmw0_pseg; 188 | reg [ 2:0] csr_dmw0_vseg; 189 | reg csr_dmw1_plv0; 190 | reg csr_dmw1_plv3; 191 | reg [ 1:0] csr_dmw1_mat; 192 | reg [ 2:0] csr_dmw1_pseg; 193 | reg [ 2:0] csr_dmw1_vseg; 194 | 195 | always @(posedge clk) begin 196 | if(reset) begin 197 | csr_crmd_plv <= 2'b0; //highest priority level 198 | csr_crmd_ie <= 1'b0; 199 | csr_crmd_da <= 1'b1;//! 200 | csr_crmd_pg <= 1'b0; 201 | csr_crmd_datf<= 2'b0; 202 | csr_crmd_datm<= 2'b0; 203 | end 204 | else if(wb_ex | refill_ex) begin 205 | if(refill_ex) begin 206 | csr_crmd_pg <= 1'h0; 207 | csr_crmd_da <= 1'h1; 208 | end 209 | csr_crmd_plv <= 2'b0; //when exception happens, set highest priority level 210 | csr_crmd_ie <= 1'b0; //when exception happens, set interrupt disenble, to mask interrupt 211 | end 212 | else if(ertn_flush) begin 213 | if(csr_estat_ecode == `ECODE_TLBR) begin 214 | csr_crmd_pg <= 1'h1; 215 | csr_crmd_da <= 1'h0; 216 | end 217 | csr_crmd_plv <= csr_prmd_pplv; //when ERTN, recover pplv 218 | csr_crmd_ie <= csr_prmd_pie; //when ERTN, recover pie 219 | end 220 | else if(csr_we && csr_num==`CSR_CRMD) begin //csrwr, csrxchg 221 | csr_crmd_plv <= csr_wmask[`CSR_CRMD_PLV] & csr_wvalue[`CSR_CRMD_PLV] 222 | | ~csr_wmask[`CSR_CRMD_PLV] & csr_crmd_plv; 223 | csr_crmd_ie <= csr_wmask[`CSR_CRMD_IE] & csr_wvalue[`CSR_CRMD_IE] 224 | | ~csr_wmask[`CSR_CRMD_IE] & csr_crmd_ie; 225 | csr_crmd_da <= csr_wmask[`CSR_CRMD_DA] & csr_wvalue[`CSR_CRMD_DA] 226 | | ~csr_wmask[`CSR_CRMD_DA] & csr_crmd_da; 227 | csr_crmd_pg <= csr_wmask[`CSR_CRMD_PG] & csr_wvalue[`CSR_CRMD_PG] 228 | | ~csr_wmask[`CSR_CRMD_PG] & csr_crmd_pg; 229 | csr_crmd_datf <= csr_wmask[`CSR_CRMD_DATF] & csr_wvalue[`CSR_CRMD_DATF] 230 | | ~csr_wmask[`CSR_CRMD_DATF] & csr_crmd_datf; 231 | csr_crmd_datm <= csr_wmask[`CSR_CRMD_DATM] & csr_wvalue[`CSR_CRMD_DATM] 232 | | ~csr_wmask[`CSR_CRMD_DATM] & csr_crmd_datm; 233 | end 234 | end 235 | 236 | assign csr_crmd_rvalue = {23'b0, //31:9 237 | csr_crmd_datm, //8:7 238 | csr_crmd_datf, //6:5 239 | csr_crmd_pg, //4 240 | csr_crmd_da, //3 241 | csr_crmd_ie, //2 242 | csr_crmd_plv //1:0 243 | }; 244 | 245 | always @(posedge clk) begin 246 | if(reset) begin 247 | csr_prmd_pplv <= 2'b0; //when exception happens, save context 248 | csr_prmd_pie <= 1'b0; 249 | end 250 | if((wb_ex | refill_ex) && csr_crmd_rvalue[2:0]!=3'b000) begin //!!! 251 | csr_prmd_pplv <= csr_crmd_plv; //when exception happens, save context 252 | csr_prmd_pie <= csr_crmd_ie ; 253 | end 254 | else if(csr_we && csr_num==`CSR_PRMD) begin 255 | csr_prmd_pplv <= csr_wmask[`CSR_PRMD_PPLV] & csr_wvalue[`CSR_PRMD_PPLV] 256 | | ~csr_wmask[`CSR_PRMD_PPLV] & csr_prmd_pplv; 257 | csr_prmd_pie <= csr_wmask[`CSR_PRMD_PIE] & csr_wvalue[`CSR_PRMD_PIE] 258 | | ~csr_wmask[`CSR_PRMD_PIE] & csr_prmd_pie; 259 | end 260 | end 261 | 262 | wire [31:0] csr_prmd_rvalue = {29'b0 , //31:3 263 | csr_prmd_pie , //2 264 | csr_prmd_pplv //1:0 265 | }; 266 | 267 | always @ (posedge clk) begin 268 | if (reset) 269 | csr_ecfg_lie <= 13'b0; 270 | else if(csr_we && csr_num == `CSR_ECFG) 271 | csr_ecfg_lie <= csr_wmask[`CSR_ECFG_LIE] & csr_wvalue[`CSR_ECFG_LIE] 272 | | ~csr_wmask[`CSR_ECFG_LIE] & csr_ecfg_lie; 273 | end 274 | 275 | 276 | wire [31:0] csr_ecfg_rvalue = {19'b0, //31:13 277 | csr_ecfg_lie //12:0 278 | }; 279 | 280 | always @(posedge clk) begin 281 | if(reset) 282 | csr_estat_is[1:0] <= 2'b0; 283 | else if(csr_we && csr_num==`CSR_ESTAT) 284 | csr_estat_is[1:0] <= csr_wmask[`CSR_ESTAT_IS10] & csr_wvalue[`CSR_ESTAT_IS10] 285 | | ~csr_wmask[`CSR_ESTAT_IS10] & csr_estat_is[1:0]; 286 | 287 | csr_estat_is[9:2] <= 8'b0;//hw_int_in[7:0];//hardware interrupt 288 | csr_estat_is[10] <= 1'b0; //no define 289 | 290 | if (csr_tcfg_en && timer_cnt[31:0]==32'b0) 291 | csr_estat_is[11] <= 1'b1; //timer interrupt 292 | else if (csr_we && csr_num==`CSR_TICLR && csr_wmask[`CSR_TICLR_CLR] && csr_wvalue[`CSR_TICLR_CLR]) 293 | csr_estat_is[11] <= 1'b0; // Finish in lab 9 294 | 295 | csr_estat_is[12] <= 1'b0;//ipi_int_in; //ipi interrupt 296 | end 297 | 298 | always @(posedge clk) begin 299 | if((wb_ex | refill_ex) & ~ertn_flush) begin 300 | csr_estat_ecode <= wb_ecode; 301 | csr_estat_esubcode <= wb_esubcode; 302 | end 303 | end 304 | 305 | wire [31:0] csr_estat_rvalue = {1'b0 , //31 306 | csr_estat_esubcode, //30:22 307 | csr_estat_ecode , //21:16, exception types 308 | 3'b0 , //15:13 309 | csr_estat_is[12:2], //12:2,other interrupt 310 | csr_estat_is[ 1:0] //1:0, software interrupt 311 | }; 312 | 313 | always @(posedge clk) begin 314 | if(reset) 315 | csr_era_pc <= 32'b0; 316 | else if((wb_ex | refill_ex) & ~ertn_flush) 317 | csr_era_pc <= wb_pc; 318 | else if(csr_we && csr_num==`CSR_ERA) 319 | csr_era_pc <= csr_wmask[`CSR_ERA_PC] & csr_wvalue[`CSR_ERA_PC] 320 | | ~csr_wmask[`CSR_ERA_PC] & csr_era_pc; 321 | end 322 | 323 | wire [31:0] csr_era_rvalue = csr_era_pc; 324 | assign ex_era = csr_era_rvalue; 325 | 326 | always @(posedge clk) begin 327 | if(reset) begin 328 | csr_eentry_va <= 26'b0; 329 | end 330 | if(csr_we && csr_num==`CSR_EENTRY) 331 | csr_eentry_va <= csr_wmask[`CSR_EENTRY_VA] & csr_wvalue[`CSR_EENTRY_VA] 332 | | ~csr_wmask[`CSR_EENTRY_VA] & csr_eentry_va; 333 | end 334 | 335 | wire [31:0] csr_eentry_rvalue = {csr_eentry_va, //31:6 336 | 6'b0 // 5:0 337 | };//that is, the address must be xxx000000 338 | 339 | assign ex_entry = csr_eentry_rvalue; 340 | 341 | always @(posedge clk) begin 342 | if (reset) begin 343 | csr_save0_data <= 32'b0; 344 | csr_save1_data <= 32'b0; 345 | csr_save2_data <= 32'b0; 346 | csr_save3_data <= 32'b0; 347 | end 348 | else if(csr_we && csr_num==`CSR_SAVE0) 349 | csr_save0_data <= csr_wmask[`CSR_SAVE_DATA] & csr_wvalue[`CSR_SAVE_DATA] 350 | | ~csr_wmask[`CSR_SAVE_DATA] & csr_save0_data; 351 | else if(csr_we && csr_num==`CSR_SAVE1) 352 | csr_save1_data <= csr_wmask[`CSR_SAVE_DATA] & csr_wvalue[`CSR_SAVE_DATA] 353 | | ~csr_wmask[`CSR_SAVE_DATA] & csr_save1_data; 354 | else if(csr_we && csr_num==`CSR_SAVE2) 355 | csr_save2_data <= csr_wmask[`CSR_SAVE_DATA] & csr_wvalue[`CSR_SAVE_DATA] 356 | | ~csr_wmask[`CSR_SAVE_DATA] & csr_save2_data; 357 | else if(csr_we && csr_num==`CSR_SAVE3) 358 | csr_save3_data <= csr_wmask[`CSR_SAVE_DATA] & csr_wvalue[`CSR_SAVE_DATA] 359 | | ~csr_wmask[`CSR_SAVE_DATA] & csr_save3_data; 360 | end 361 | 362 | wire [31:0] csr_save0_rvalue = csr_save0_data; 363 | wire [31:0] csr_save1_rvalue = csr_save1_data; 364 | wire [31:0] csr_save2_rvalue = csr_save2_data; 365 | wire [31:0] csr_save3_rvalue = csr_save3_data; 366 | 367 | // BADV 368 | assign wb_ex_addr_err = wb_ecode == `ECODE_ADE || wb_ecode == `ECODE_ALE 369 | || wb_ecode == `ECODE_TLBR || wb_ecode == `ECODE_PIF || wb_ecode == `ECODE_PIS || wb_ecode == `ECODE_PIL || wb_ecode == `ECODE_PME || wb_ecode == `ECODE_PPE; 370 | 371 | always @(posedge clk) begin 372 | if(reset) begin 373 | csr_badv_vaddr <= 32'b0; 374 | end 375 | if ((wb_ex | refill_ex) && wb_ex_addr_err) 376 | csr_badv_vaddr <= (wb_ecode == `ECODE_ADE && wb_esubcode == `ESUBCODE_ADEF) ? wb_pc : wb_vaddr; 377 | end 378 | 379 | wire [31:0] csr_badv_rvalue = csr_badv_vaddr; 380 | 381 | // TID 382 | always @(posedge clk) begin 383 | if (reset) 384 | csr_tid_tid <= 32'd0; 385 | else if (csr_we && csr_num == `CSR_TID) 386 | csr_tid_tid <= csr_wmask[`CSR_TID_TID] & csr_wvalue[`CSR_TID_TID] 387 | | ~csr_wmask[`CSR_TID_TID] & csr_tid_tid; 388 | end 389 | 390 | wire [31:0] csr_tid_rvalue = csr_tid_tid; 391 | 392 | // TCFG 393 | always @(posedge clk) begin 394 | if (reset) 395 | csr_tcfg_en <= 1'b0; 396 | else if (csr_we && csr_num == `CSR_TCFG) 397 | csr_tcfg_en <= csr_wmask[`CSR_TCFG_EN] & csr_wvalue[`CSR_TCFG_EN] | 398 | ~csr_wmask[`CSR_TCFG_EN] & csr_tcfg_en; 399 | 400 | if (csr_we && csr_num == `CSR_TCFG) begin 401 | csr_tcfg_periodic <= csr_wmask[`CSR_TCFG_PERIODIC] & csr_wvalue[`CSR_TCFG_PERIODIC] | 402 | ~csr_wmask[`CSR_TCFG_PERIODIC] & csr_tcfg_periodic; 403 | csr_tcfg_initval <= csr_wmask[`CSR_TCFG_INITVAL] & csr_wvalue[`CSR_TCFG_INITVAL] | 404 | ~csr_wmask[`CSR_TCFG_INITVAL] & csr_tcfg_initval; 405 | end 406 | end 407 | 408 | wire [31:0] csr_tcfg_rvalue = {csr_tcfg_initval, csr_tcfg_periodic, csr_tcfg_en}; 409 | 410 | // TVAL 411 | assign tcfg_next_value = csr_wmask[31:0] & csr_wvalue[31:0] | 412 | ~csr_wmask[31:0] & {csr_tcfg_initval, csr_tcfg_periodic, csr_tcfg_en}; 413 | 414 | always @(posedge clk) begin 415 | if (reset) 416 | timer_cnt <= 32'hffffffff; 417 | else if (csr_we && csr_num == `CSR_TCFG && tcfg_next_value[`CSR_TCFG_EN]) 418 | timer_cnt <= {tcfg_next_value[`CSR_TCFG_INITVAL], 2'b0}; 419 | else if (csr_tcfg_en && timer_cnt != 32'hffffffff) begin 420 | if (timer_cnt[31:0] == 32'b0 && csr_tcfg_periodic) 421 | timer_cnt <= {csr_tcfg_initval, 2'b0}; 422 | else 423 | timer_cnt <= timer_cnt - 1'b1; 424 | end 425 | end 426 | 427 | assign csr_tval = timer_cnt[31:0]; 428 | 429 | // TICLR 430 | assign csr_ticlr_clr = 1'b0; 431 | 432 | wire [31:0] csr_ticlr = {31'd0, csr_ticlr_clr}; 433 | 434 | // TLBIDX 435 | always @(posedge clk) begin 436 | if(reset) begin 437 | csr_tlbidx_ne <= 1'b1; 438 | csr_tlbidx_ps <= 6'b0; 439 | csr_tlbidx_index <= 4'b0; 440 | end 441 | else if(inst_tlbsrch) begin 442 | if(s1_found) begin 443 | csr_tlbidx_ne <= 1'b0; 444 | csr_tlbidx_index <= s1_index; 445 | end 446 | else 447 | csr_tlbidx_ne <= 1'b1; 448 | end 449 | else if(ws_valid && inst_tlbrd) begin 450 | csr_tlbidx_ne <= ~r_e; 451 | end 452 | else if(inst_tlbrd && r_e) begin 453 | csr_tlbidx_ps <= r_ps; 454 | end 455 | else if(csr_we && csr_num==`CSR_TLBIDX)begin 456 | csr_tlbidx_ne <= csr_wmask[`CSR_TLBIDX_NE] & csr_wvalue[`CSR_TLBIDX_NE] 457 | | ~csr_wmask[`CSR_TLBIDX_NE] & csr_tlbidx_ne; 458 | csr_tlbidx_ps <= csr_wmask[`CSR_TLBIDX_PS] & csr_wvalue[`CSR_TLBIDX_PS] 459 | | ~csr_wmask[`CSR_TLBIDX_PS] & csr_tlbidx_ps; 460 | csr_tlbidx_index <= csr_wmask[`CSR_TLBIDX_INDEX] & csr_wvalue[`CSR_TLBIDX_INDEX] 461 | | ~csr_wmask[`CSR_TLBIDX_INDEX] & csr_tlbidx_index; 462 | end 463 | end 464 | 465 | wire [31:0] csr_tlbidx_rvalue = {csr_tlbidx_ne ,//31 466 | 1'b0 ,//30 467 | csr_tlbidx_ps ,//29:24 468 | 8'b0 ,//23:16 469 | 12'b0 ,//15:4 470 | csr_tlbidx_index //3:0 471 | }; 472 | // TLBEHI 473 | always @(posedge clk) begin 474 | if(reset) begin 475 | csr_tlbehi_vppn <= 19'b0; 476 | end 477 | else if(inst_tlbrd && r_e) begin 478 | csr_tlbehi_vppn <= r_vppn; 479 | end 480 | else if (wb_ex & ~ertn_flush & (wb_ecode == `ECODE_TLBR || 481 | wb_ecode == `ECODE_PIL || 482 | wb_ecode == `ECODE_PIS || 483 | wb_ecode == `ECODE_PIF || 484 | wb_ecode == `ECODE_PME || 485 | wb_ecode == `ECODE_PPE)) begin 486 | csr_tlbehi_vppn <= wb_vaddr[31:13]; 487 | end 488 | else if(csr_we && csr_num == `CSR_TLBEHI) begin 489 | csr_tlbehi_vppn <= csr_wmask[`CSR_TLBEHI_VPPN] & csr_wvalue[`CSR_TLBEHI_VPPN] 490 | | ~csr_wmask[`CSR_TLBEHI_VPPN] & csr_tlbehi_vppn; 491 | end 492 | end 493 | 494 | assign csr_tlbehi_rvalue = {csr_tlbehi_vppn,//31:13 495 | 13'b0 //12:0 496 | }; 497 | 498 | // TLBELO0//even 499 | always @(posedge clk) begin 500 | if(reset) begin 501 | csr_tlbelo0_v <= 1'b0; 502 | csr_tlbelo0_d <= 1'b0; 503 | csr_tlbelo0_plv <= 2'b0; 504 | csr_tlbelo0_mat <= 2'b0; 505 | csr_tlbelo0_g <= 1'b0; 506 | csr_tlbelo0_ppn <= 24'b0; 507 | end 508 | else if(inst_tlbrd && r_e) begin 509 | csr_tlbelo0_v <= r_v0; 510 | csr_tlbelo0_d <= r_d0; 511 | csr_tlbelo0_plv <= r_plv0; 512 | csr_tlbelo0_mat <= r_mat0; 513 | csr_tlbelo0_g <= r_g; 514 | csr_tlbelo0_ppn <= r_ppn0; 515 | end 516 | else if(csr_we && csr_num == `CSR_TLBELO0) begin 517 | csr_tlbelo0_v <= csr_wmask[`CSR_TLBELO_V] & csr_wvalue[`CSR_TLBELO_V] 518 | | ~csr_wmask[`CSR_TLBELO_V] & csr_tlbelo0_v; 519 | csr_tlbelo0_d <= csr_wmask[`CSR_TLBELO_D] & csr_wvalue[`CSR_TLBELO_D] 520 | | ~csr_wmask[`CSR_TLBELO_D] & csr_tlbelo0_d; 521 | csr_tlbelo0_plv <= csr_wmask[`CSR_TLBELO_PLV] & csr_wvalue[`CSR_TLBELO_PLV] 522 | | ~csr_wmask[`CSR_TLBELO_PLV] & csr_tlbelo0_plv; 523 | csr_tlbelo0_mat <= csr_wmask[`CSR_TLBELO_MAT] & csr_wvalue[`CSR_TLBELO_MAT] 524 | | ~csr_wmask[`CSR_TLBELO_MAT] & csr_tlbelo0_mat; 525 | csr_tlbelo0_ppn <= csr_wmask[`CSR_TLBELO_PPN] & csr_wvalue[`CSR_TLBELO_PPN] 526 | | ~csr_wmask[`CSR_TLBELO_PPN] & csr_tlbelo0_ppn; 527 | csr_tlbelo0_g <= csr_wmask[`CSR_TLBELO_G] & csr_wvalue[`CSR_TLBELO_G] 528 | | ~csr_wmask[`CSR_TLBELO_G] & csr_tlbelo0_g; 529 | end 530 | end 531 | 532 | wire [31:0] csr_tlbelo0_rvalue = {csr_tlbelo0_ppn,//31:8 533 | 1'b0 ,//7 534 | csr_tlbelo0_g ,//6 535 | csr_tlbelo0_mat,//5:4 536 | csr_tlbelo0_plv,//3:2 537 | csr_tlbelo0_d ,//1 538 | csr_tlbelo0_v //0 539 | }; 540 | 541 | // TLBELO1//odd 542 | always @(posedge clk) begin 543 | if(reset) begin 544 | csr_tlbelo1_v <= 1'b0; 545 | csr_tlbelo1_d <= 1'b0; 546 | csr_tlbelo1_plv <= 2'b0; 547 | csr_tlbelo1_mat <= 2'b0; 548 | csr_tlbelo1_g <= 1'b0; 549 | csr_tlbelo1_ppn <= 24'b0; 550 | end 551 | else if(inst_tlbrd && r_e) begin 552 | csr_tlbelo1_v <= r_v1; 553 | csr_tlbelo1_d <= r_d1; 554 | csr_tlbelo1_plv <= r_plv1; 555 | csr_tlbelo1_mat <= r_mat1; 556 | csr_tlbelo1_g <= r_g; 557 | csr_tlbelo1_ppn <= r_ppn1; 558 | end 559 | else if(csr_we && csr_num == `CSR_TLBELO1) begin 560 | csr_tlbelo1_v <= csr_wmask[`CSR_TLBELO_V] & csr_wvalue[`CSR_TLBELO_V] 561 | | ~csr_wmask[`CSR_TLBELO_V] & csr_tlbelo1_v; 562 | csr_tlbelo1_d <= csr_wmask[`CSR_TLBELO_D] & csr_wvalue[`CSR_TLBELO_D] 563 | | ~csr_wmask[`CSR_TLBELO_D] & csr_tlbelo1_d; 564 | csr_tlbelo1_plv <= csr_wmask[`CSR_TLBELO_PLV] & csr_wvalue[`CSR_TLBELO_PLV] 565 | | ~csr_wmask[`CSR_TLBELO_PLV] & csr_tlbelo1_plv; 566 | csr_tlbelo1_mat <= csr_wmask[`CSR_TLBELO_MAT] & csr_wvalue[`CSR_TLBELO_MAT] 567 | | ~csr_wmask[`CSR_TLBELO_MAT] & csr_tlbelo1_mat; 568 | csr_tlbelo1_ppn <= csr_wmask[`CSR_TLBELO_PPN] & csr_wvalue[`CSR_TLBELO_PPN] 569 | | ~csr_wmask[`CSR_TLBELO_PPN] & csr_tlbelo1_ppn; 570 | csr_tlbelo1_g <= csr_wmask[`CSR_TLBELO_G] & csr_wvalue[`CSR_TLBELO_G] 571 | | ~csr_wmask[`CSR_TLBELO_G] & csr_tlbelo1_g; 572 | end 573 | end 574 | 575 | wire [31:0] csr_tlbelo1_rvalue = {csr_tlbelo1_ppn,//31:8 576 | 1'b0 ,//7 577 | csr_tlbelo1_g ,//6 578 | csr_tlbelo1_mat,//5:4 579 | csr_tlbelo1_plv,//3:2 580 | csr_tlbelo1_d ,//1 581 | csr_tlbelo1_v //0 582 | }; 583 | 584 | // ASID 585 | always @(posedge clk) begin 586 | if(reset) begin 587 | csr_asid_asid <= 10'b0; 588 | end 589 | else if(inst_tlbrd && r_e) begin 590 | csr_asid_asid <= r_asid; 591 | end 592 | else if(csr_we && csr_num == `CSR_ASID)begin 593 | csr_asid_asid <= csr_wmask[`CSR_ASID_ASID] & csr_wvalue[`CSR_ASID_ASID] 594 | | ~csr_wmask[`CSR_ASID_ASID] & csr_asid_asid; 595 | end 596 | end 597 | 598 | assign csr_asid_rvalue = {8'b0 ,//31:24 599 | csr_asid_asidbits,//23:16 600 | 6'b0 ,//15:10 601 | csr_asid_asid //9:0 602 | }; 603 | // TLBRENTRY 604 | always @(posedge clk ) begin 605 | if(reset)begin 606 | csr_tlbrentry_pa <= 26'b0; 607 | end 608 | else if(csr_we && csr_num == `CSR_TLBRENTRY) begin 609 | csr_tlbrentry_pa <= csr_wmask[`CSR_TLBRENTRY_PA] & csr_wvalue[`CSR_TLBRENTRY_PA] 610 | | ~csr_wmask[`CSR_TLBRENTRY_PA] & csr_tlbrentry_pa; 611 | end 612 | end 613 | 614 | assign csr_tlbrentry_rvalue = {csr_tlbrentry_pa,//31:6 615 | 6'b0 //5:0 616 | }; 617 | // DMW0 618 | always @ (posedge clk) begin 619 | if (reset) begin 620 | csr_dmw0_vseg <= 3'b0; 621 | csr_dmw0_pseg <= 3'b0; 622 | csr_dmw0_mat <= 2'b0; 623 | csr_dmw0_plv3 <= 1'b0; 624 | csr_dmw0_plv0 <= 1'b0; 625 | end 626 | else if (csr_we & (csr_num == `CSR_DMW0)) begin 627 | csr_dmw0_vseg <= csr_wmask[`CSR_DMW_VSEG] & csr_wvalue[`CSR_DMW_VSEG] 628 | | ~csr_wmask[`CSR_DMW_VSEG] & csr_dmw0_vseg; 629 | csr_dmw0_pseg <= csr_wmask[`CSR_DMW_PSEG] & csr_wvalue[`CSR_DMW_PSEG] 630 | | ~csr_wmask[`CSR_DMW_PSEG] & csr_dmw0_pseg; 631 | csr_dmw0_mat <= csr_wmask[`CSR_DMW_MAT] & csr_wvalue[`CSR_DMW_MAT] 632 | | ~csr_wmask[`CSR_DMW_MAT] & csr_dmw0_mat; 633 | csr_dmw0_plv3 <= csr_wmask[`CSR_DMW_PLV3] & csr_wvalue[`CSR_DMW_PLV3] 634 | | ~csr_wmask[`CSR_DMW_PLV3] & csr_dmw0_plv3; 635 | csr_dmw0_plv0 <= csr_wmask[`CSR_DMW_PLV0] & csr_wvalue[`CSR_DMW_PLV0] 636 | | ~csr_wmask[`CSR_DMW_PLV0] & csr_dmw0_plv0; 637 | end 638 | end 639 | 640 | assign csr_dmw0_rvalue = {csr_dmw0_vseg, //31:29 641 | 1'b0, //28 642 | csr_dmw0_pseg, //27:25 643 | 19'b0, //24:6 644 | csr_dmw0_mat, //5:4 645 | csr_dmw0_plv3, //3 646 | 2'b0, //2:1 647 | csr_dmw0_plv0 //0 648 | }; 649 | 650 | // DMW1 651 | always @ (posedge clk) begin 652 | if (reset) begin 653 | csr_dmw1_vseg <= 3'b0; 654 | csr_dmw1_pseg <= 3'b0; 655 | csr_dmw1_mat <= 2'b0; 656 | csr_dmw1_plv3 <= 1'b0; 657 | csr_dmw1_plv0 <= 1'b0; 658 | end 659 | else if (csr_we & (csr_num == `CSR_DMW1)) begin 660 | csr_dmw1_vseg <= csr_wmask[`CSR_DMW_VSEG] & csr_wvalue[`CSR_DMW_VSEG] 661 | | ~csr_wmask[`CSR_DMW_VSEG] & csr_dmw1_vseg; 662 | csr_dmw1_pseg <= csr_wmask[`CSR_DMW_PSEG] & csr_wvalue[`CSR_DMW_PSEG] 663 | | ~csr_wmask[`CSR_DMW_PSEG] & csr_dmw1_pseg; 664 | csr_dmw1_mat <= csr_wmask[`CSR_DMW_MAT] & csr_wvalue[`CSR_DMW_MAT] 665 | | ~csr_wmask[`CSR_DMW_MAT] & csr_dmw1_mat; 666 | csr_dmw1_plv3 <= csr_wmask[`CSR_DMW_PLV3] & csr_wvalue[`CSR_DMW_PLV3] 667 | | ~csr_wmask[`CSR_DMW_PLV3] & csr_dmw1_plv3; 668 | csr_dmw1_plv0 <= csr_wmask[`CSR_DMW_PLV0] & csr_wvalue[`CSR_DMW_PLV0] 669 | | ~csr_wmask[`CSR_DMW_PLV0] & csr_dmw1_plv0; 670 | end 671 | end 672 | 673 | assign csr_dmw1_rvalue = {csr_dmw1_vseg, //31:29 674 | 1'b0, //28 675 | csr_dmw1_pseg, //27:25 676 | 19'b0, //24:6 677 | csr_dmw1_mat, //5:4 678 | csr_dmw1_plv3, //3 679 | 2'b0, //2:1 680 | csr_dmw1_plv0 //0 681 | }; 682 | 683 | reg [ 3:0] tlbfill_index; 684 | always @(posedge clk)begin 685 | if(reset)begin 686 | tlbfill_index <= 4'b0; 687 | end 688 | else if(inst_tlbfill & ws_valid) begin 689 | if(tlbfill_index == 4'd15) begin 690 | tlbfill_index <= 4'b0; 691 | end 692 | else begin 693 | tlbfill_index <= tlbfill_index + 4'b1; 694 | end 695 | end 696 | end 697 | 698 | assign we = ws_valid && inst_tlbwr || inst_tlbfill;; 699 | assign w_index = ws_valid && inst_tlbfill ?tlbfill_index : csr_tlbidx_index; 700 | assign w_e = csr_estat_ecode == 6'h3f ? 1'b1 : ~csr_tlbidx_ne; 701 | assign w_vppn = csr_tlbehi_vppn; 702 | assign w_ps = csr_tlbidx_ps; 703 | assign w_asid = csr_asid_asid; 704 | assign w_g = csr_tlbelo0_g && csr_tlbelo1_g; 705 | assign w_ppn0 = csr_tlbelo0_ppn; 706 | assign w_plv0 = csr_tlbelo0_plv; 707 | assign w_mat0 = csr_tlbelo0_mat; 708 | assign w_d0 = csr_tlbelo0_d; 709 | assign w_v0 = csr_tlbelo0_v; 710 | assign w_ppn1 = csr_tlbelo1_ppn; 711 | assign w_plv1 = csr_tlbelo1_plv; 712 | assign w_mat1 = csr_tlbelo1_mat; 713 | assign w_d1 = csr_tlbelo1_d; 714 | assign w_v1 = csr_tlbelo1_v; 715 | assign r_index = csr_tlbidx_index; 716 | 717 | assign csr_rvalue = {32{csr_num==`CSR_CRMD }} & csr_crmd_rvalue 718 | | {32{csr_num==`CSR_PRMD }} & csr_prmd_rvalue 719 | | {32{csr_num==`CSR_ESTAT }} & csr_estat_rvalue 720 | | {32{csr_num==`CSR_ERA }} & csr_era_rvalue 721 | | {32{csr_num==`CSR_EENTRY }} & csr_eentry_rvalue 722 | | {32{csr_num==`CSR_ECFG }} & csr_ecfg_rvalue 723 | | {32{csr_num==`CSR_SAVE0 }} & csr_save0_rvalue 724 | | {32{csr_num==`CSR_SAVE1 }} & csr_save1_rvalue 725 | | {32{csr_num==`CSR_SAVE2 }} & csr_save2_rvalue 726 | | {32{csr_num==`CSR_SAVE3 }} & csr_save3_rvalue 727 | | {32{csr_num==`CSR_BADV }} & csr_badv_rvalue 728 | | {32{csr_num==`CSR_TID }} & csr_tid_rvalue 729 | | {32{csr_num==`CSR_TCFG }} & csr_tcfg_rvalue 730 | | {32{csr_num==`CSR_TVAL }} & csr_tval 731 | | {32{csr_num==`CSR_TICLR }} & csr_ticlr 732 | | {32{csr_num==`CSR_TLBIDX }} & csr_tlbidx_rvalue 733 | | {32{csr_num==`CSR_TLBEHI }} & csr_tlbehi_rvalue 734 | | {32{csr_num==`CSR_TLBELO0 }} & csr_tlbelo0_rvalue 735 | | {32{csr_num==`CSR_TLBELO1 }} & csr_tlbelo1_rvalue 736 | | {32{csr_num==`CSR_ASID }} & csr_asid_rvalue 737 | | {32{csr_num==`CSR_TLBRENTRY}} & csr_tlbrentry_rvalue 738 | | {32{csr_num==`CSR_DMW0 }} & csr_dmw0_rvalue 739 | | {32{csr_num==`CSR_DMW1 }} & csr_dmw1_rvalue; 740 | 741 | assign has_int = ((csr_estat_is[11:0] & csr_ecfg_lie[11:0]) != 12'b0) 742 | && (csr_crmd_ie == 1'b1); 743 | 744 | reg [63:0] cnt; 745 | always @(posedge clk) begin 746 | if (reset) 747 | cnt <= 64'b0; 748 | else 749 | cnt <= cnt + 1'b1; 750 | end 751 | 752 | assign counter = cnt; 753 | assign counter_id = csr_tid_tid; 754 | 755 | endmodule -------------------------------------------------------------------------------- /regfile.v: -------------------------------------------------------------------------------- 1 | module regfile( 2 | input clk, 3 | // READ PORT 1 4 | input [ 4:0] raddr1, 5 | output [31:0] rdata1, 6 | // READ PORT 2 7 | input [ 4:0] raddr2, 8 | output [31:0] rdata2, 9 | // WRITE PORT 10 | input we, //write enable, HIGH valid 11 | input [ 4:0] waddr, 12 | input [31:0] wdata 13 | ); 14 | reg [31:0] rf[31:0]; 15 | 16 | //WRITE 17 | always @(posedge clk) begin 18 | if (we) rf[waddr]<= wdata; 19 | end 20 | 21 | //READ OUT 1 22 | assign rdata1 = (raddr1==5'b0) ? 32'b0 : rf[raddr1]; 23 | 24 | //READ OUT 2 25 | assign rdata2 = (raddr2==5'b0) ? 32'b0 : rf[raddr2]; 26 | 27 | endmodule -------------------------------------------------------------------------------- /tlb.v: -------------------------------------------------------------------------------- 1 | module tlb 2 | #( 3 | parameter TLBNUM = 16 4 | ) 5 | ( 6 | input clk, 7 | // search port 0 (for fetch) 8 | input [ 18:0] s0_vppn,//虚双页号 9 | input s0_va_bit12, 10 | input [ 9:0] s0_asid,//地址空间标识 11 | output s0_found, 12 | output [$clog2(TLBNUM)-1:0] s0_index, 13 | output [ 19:0] s0_ppn,//物理页号 14 | output [ 5:0] s0_ps,//页大小 15 | output [ 1:0] s0_plv,//特权等级 16 | output [ 1:0] s0_mat,//存储访问类型 17 | output s0_d, 18 | output s0_v, 19 | // search port 1 (for load/store) 20 | input [ 18:0] s1_vppn, 21 | input s1_va_bit12, 22 | input [ 9:0] s1_asid, 23 | output s1_found, 24 | output [$clog2(TLBNUM)-1:0] s1_index, 25 | output [ 19:0] s1_ppn, 26 | output [ 5:0] s1_ps, 27 | output [ 1:0] s1_plv, 28 | output [ 1:0] s1_mat, 29 | output s1_d, 30 | output s1_v, 31 | // invtlb opcode 32 | input [ 4:0] invtlb_op, 33 | input inst_invtlb, 34 | // write port 35 | input we, //w(rite) e(nable) 36 | input [$clog2(TLBNUM)-1:0] w_index, 37 | input w_e,//存在位 38 | input [ 18:0] w_vppn, 39 | input [ 5:0] w_ps, 40 | input [ 9:0] w_asid, 41 | input w_g,//全局标识位 42 | input [ 19:0] w_ppn0, 43 | input [ 1:0] w_plv0, 44 | input [ 1:0] w_mat0, 45 | input w_d0, 46 | input w_v0, 47 | input [ 19:0] w_ppn1, 48 | input [ 1:0] w_plv1, 49 | input [ 1:0] w_mat1, 50 | input w_d1, 51 | input w_v1, 52 | // read port 53 | input [$clog2(TLBNUM)-1:0] r_index, 54 | output r_e, 55 | output [ 18:0] r_vppn, 56 | output [ 5:0] r_ps, 57 | output [ 9:0] r_asid, 58 | output r_g, 59 | output [ 19:0] r_ppn0, 60 | output [ 1:0] r_plv0, 61 | output [ 1:0] r_mat0, 62 | output r_d0, 63 | output r_v0, 64 | output [ 19:0] r_ppn1, 65 | output [ 1:0] r_plv1, 66 | output [ 1:0] r_mat1, 67 | output r_d1, 68 | output r_v1 69 | ); 70 | reg [TLBNUM-1:0] tlb_e; 71 | reg [TLBNUM-1:0] tlb_ps4MB; //pagesize 1:4MB, 0:4KB 72 | reg [ 18 :0] tlb_vppn [TLBNUM-1:0]; 73 | reg [ 9 :0] tlb_asid [TLBNUM-1:0]; 74 | reg tlb_g [TLBNUM-1:0]; 75 | reg [ 19 :0] tlb_ppn0 [TLBNUM-1:0]; 76 | reg [ 1 :0] tlb_plv0 [TLBNUM-1:0]; 77 | reg [ 1 :0] tlb_mat0 [TLBNUM-1:0]; 78 | reg tlb_d0 [TLBNUM-1:0]; 79 | reg tlb_v0 [TLBNUM-1:0]; 80 | reg [ 19 :0] tlb_ppn1 [TLBNUM-1:0]; 81 | reg [ 1 :0] tlb_plv1 [TLBNUM-1:0]; 82 | reg [ 1 :0] tlb_mat1 [TLBNUM-1:0]; 83 | reg tlb_d1 [TLBNUM-1:0]; 84 | reg tlb_v1 [TLBNUM-1:0]; 85 | 86 | wire [15:0] match0; 87 | wire [15:0] match1; 88 | wire cond1 [TLBNUM-1:0]; 89 | wire cond2 [TLBNUM-1:0]; 90 | wire cond3 [TLBNUM-1:0]; 91 | wire cond4 [TLBNUM-1:0]; 92 | wire inv_match [TLBNUM-1:0]; 93 | 94 | genvar i; 95 | generate 96 | for (i = 0; i < TLBNUM; i = i + 1) 97 | begin: tlb_match 98 | assign match0[i] = (s0_vppn[18:10] == tlb_vppn[i][18:10]) 99 | && (tlb_ps4MB[i] || s0_vppn[9:0] == tlb_vppn[i][9:0]) 100 | && (s0_asid == tlb_asid[i] || tlb_g[i]); 101 | 102 | assign match1[i] = (s1_vppn[18:10] == tlb_vppn[i][18:10]) 103 | && (tlb_ps4MB[i] || s1_vppn[9:0] == tlb_vppn[i][ 9: 0]) 104 | && (s1_asid == tlb_asid[i] || tlb_g[i]); 105 | 106 | assign cond1[i] = tlb_g[i] == 0; 107 | assign cond2[i] = tlb_g[i] == 1; 108 | assign cond3[i] = tlb_asid[i] == s1_asid; 109 | assign cond4[i] = (s1_vppn[18:10] == tlb_vppn[i][18:10]) 110 | && (tlb_ps4MB[i] || s1_vppn[9:0]==tlb_vppn[i][9:0]); 111 | 112 | assign inv_match[i] = (invtlb_op == 0 || invtlb_op == 1) & (cond1[i] || cond2[i]) | 113 | (invtlb_op == 2) & cond2[i] | 114 | (invtlb_op == 3) & cond1[i] | 115 | (invtlb_op == 4) & (cond1[i] && cond3[i]) | 116 | (invtlb_op == 5) & (cond1[i] && cond3[i] && cond4[i]) | 117 | (invtlb_op == 6) & match1[i]; 118 | 119 | 120 | always @(posedge clk )begin 121 | if (we && w_index == i) begin 122 | tlb_e [i] <= w_e; 123 | tlb_ps4MB[i] <= (w_ps == 6'd22); 124 | tlb_vppn [i] <= w_vppn; 125 | tlb_asid [i] <= w_asid; 126 | tlb_g [i] <= w_g; 127 | tlb_ppn0 [i] <= w_ppn0; 128 | tlb_plv0 [i] <= w_plv0; 129 | tlb_mat0 [i] <= w_mat0; 130 | tlb_d0 [i] <= w_d0; 131 | tlb_v0 [i] <= w_v0; 132 | tlb_ppn1 [i] <= w_ppn1; 133 | tlb_plv1 [i] <= w_plv1; 134 | tlb_mat1 [i] <= w_mat1; 135 | tlb_d1 [i] <= w_d1; 136 | tlb_v1 [i] <= w_v1; 137 | end 138 | else if (inv_match[i] & inst_invtlb) begin 139 | tlb_e [i] <= 1'b0; 140 | end 141 | end 142 | end 143 | endgenerate 144 | 145 | /* ------------------- search port 0 ------------------- */ 146 | assign s0_found = (match0 != 16'd0); 147 | assign s0_index = {4{match0[ 0]}} & 4'd0 148 | | {4{match0[ 1]}} & 4'd1 149 | | {4{match0[ 2]}} & 4'd2 150 | | {4{match0[ 3]}} & 4'd3 151 | | {4{match0[ 4]}} & 4'd4 152 | | {4{match0[ 5]}} & 4'd5 153 | | {4{match0[ 6]}} & 4'd6 154 | | {4{match0[ 7]}} & 4'd7 155 | | {4{match0[ 8]}} & 4'd8 156 | | {4{match0[ 9]}} & 4'd9 157 | | {4{match0[10]}} & 4'd10 158 | | {4{match0[11]}} & 4'd11 159 | | {4{match0[12]}} & 4'd12 160 | | {4{match0[13]}} & 4'd13 161 | | {4{match0[14]}} & 4'd14 162 | | {4{match0[15]}} & 4'd15; 163 | wire s0_odd = tlb_ps4MB[s0_index] ? s0_vppn[9] : s0_va_bit12; 164 | assign s0_ppn = s0_odd ? tlb_ppn1[s0_index] : tlb_ppn0[s0_index]; 165 | assign s0_ps = {6{tlb_ps4MB[s0_index]}} & 6'd22 166 | | {6{~tlb_ps4MB[s0_index]}} & 6'd12; 167 | assign s0_plv = {2{s0_odd}} & tlb_plv1[s0_index] 168 | | {2{~s0_odd}} & tlb_plv0[s0_index]; 169 | assign s0_mat = {2{s0_odd}} & tlb_mat1[s0_index] 170 | | {2{~s0_odd}} & tlb_mat0[s0_index]; 171 | assign s0_d = s0_odd & tlb_d1[s0_index] 172 | | ~s0_odd & tlb_d0[s0_index]; 173 | assign s0_v = s0_odd & tlb_v1[s0_index] 174 | | ~s0_odd & tlb_v0[s0_index]; 175 | 176 | /* ------------------- search port 1 ------------------- */ 177 | assign s1_found = (match1 != 16'b0); 178 | assign s1_index = {4{match1[ 0]}} & 4'd0 179 | | {4{match1[ 1]}} & 4'd1 180 | | {4{match1[ 2]}} & 4'd2 181 | | {4{match1[ 3]}} & 4'd3 182 | | {4{match1[ 4]}} & 4'd4 183 | | {4{match1[ 5]}} & 4'd5 184 | | {4{match1[ 6]}} & 4'd6 185 | | {4{match1[ 7]}} & 4'd7 186 | | {4{match1[ 8]}} & 4'd8 187 | | {4{match1[ 9]}} & 4'd9 188 | | {4{match1[10]}} & 4'd10 189 | | {4{match1[11]}} & 4'd11 190 | | {4{match1[12]}} & 4'd12 191 | | {4{match1[13]}} & 4'd13 192 | | {4{match1[14]}} & 4'd14 193 | | {4{match1[15]}} & 4'd15; 194 | wire s1_odd = tlb_ps4MB[s1_index] ? s1_vppn[9] : s1_va_bit12; 195 | assign s1_ppn = s1_odd ? tlb_ppn1[s1_index] : tlb_ppn0[s1_index]; 196 | assign s1_ps = {6{tlb_ps4MB[s1_index]}} & 6'd22 197 | | {6{~tlb_ps4MB[s1_index]}} & 6'd12; 198 | assign s1_plv = {2{s1_odd}} & tlb_plv1[s1_index] 199 | | {2{~s1_odd}} & tlb_plv0[s1_index]; 200 | assign s1_mat = {2{s1_odd}} & tlb_mat1[s1_index] 201 | | {2{~s1_odd}} & tlb_mat0[s1_index]; 202 | assign s1_d = s1_odd & tlb_d1[s1_index] 203 | | ~s1_odd & tlb_d0[s1_index]; 204 | assign s1_v = s1_odd & tlb_v1[s1_index] 205 | | ~s1_odd & tlb_v0[s1_index]; 206 | 207 | /* ------------------- read port ------------------- */ 208 | assign r_e = tlb_e[r_index]; 209 | assign r_vppn = tlb_vppn[r_index]; 210 | assign r_ps = tlb_ps4MB[r_index] ? 6'd22 : 6'd12; 211 | assign r_asid = tlb_asid[r_index]; 212 | assign r_g = tlb_g[r_index]; 213 | assign r_ppn0 = tlb_ppn0[r_index]; 214 | assign r_plv0 = tlb_plv0[r_index]; 215 | assign r_mat0 = tlb_mat0[r_index]; 216 | assign r_d0 = tlb_d0[r_index]; 217 | assign r_v0 = tlb_v0[r_index]; 218 | assign r_ppn1 = tlb_ppn1[r_index]; 219 | assign r_plv1 = tlb_plv1[r_index]; 220 | assign r_mat1 = tlb_mat1[r_index]; 221 | assign r_d1 = tlb_d1[r_index]; 222 | assign r_v1 = tlb_v1[r_index]; 223 | 224 | endmodule -------------------------------------------------------------------------------- /tools.v: -------------------------------------------------------------------------------- 1 | module decoder_2_4( 2 | input [ 1:0] in, 3 | output [ 3:0] out 4 | ); 5 | 6 | genvar i; 7 | generate for (i=0; i<4; i=i+1) begin : gen_for_dec_2_4 8 | assign out[i] = (in == i); 9 | end endgenerate 10 | 11 | endmodule 12 | 13 | 14 | module decoder_4_16( 15 | input [ 3:0] in, 16 | output [15:0] out 17 | ); 18 | 19 | genvar i; 20 | generate for (i=0; i<16; i=i+1) begin : gen_for_dec_4_16 21 | assign out[i] = (in == i); 22 | end endgenerate 23 | 24 | endmodule 25 | 26 | 27 | module decoder_5_32( 28 | input [ 4:0] in, 29 | output [31:0] out 30 | ); 31 | 32 | genvar i; 33 | generate for (i=0; i<32; i=i+1) begin : gen_for_dec_5_32 34 | assign out[i] = (in == i); 35 | end endgenerate 36 | 37 | endmodule 38 | 39 | 40 | module decoder_6_64( 41 | input [ 5:0] in, 42 | output [63:0] out 43 | ); 44 | 45 | genvar i; 46 | generate for (i=0; i<64; i=i+1) begin : gen_for_dec_6_64 47 | assign out[i] = (in == i); 48 | end endgenerate 49 | 50 | endmodule 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /wb_stage.v: -------------------------------------------------------------------------------- 1 | `include "mycpu.h" 2 | 3 | module wb_stage#( 4 | parameter TLBNUM = 16 5 | ) 6 | ( 7 | input clk , 8 | input reset , 9 | //allowin 10 | output ws_allowin , 11 | //from ms 12 | input ms_to_ws_valid, 13 | input [`MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus , 14 | //to rf: for write back 15 | output [`WS_TO_RF_BUS_WD -1:0] ws_to_rf_bus , 16 | output final_ex , 17 | //trace debug interface 18 | output [31 :0] debug_wb_pc , 19 | output [ 3 :0] debug_wb_rf_wen , 20 | output [ 4 :0] debug_wb_rf_wnum, 21 | output [31 :0] debug_wb_rf_wdata, 22 | output [`WS_FORWARD_WD -1:0] ws_forward, 23 | output [`WS_TO_FS_BUS_WD -1:0] ws_to_fs_bus, 24 | 25 | // counter to es 26 | output [63:0] counter, 27 | output back_ertn_flush, 28 | output back_ex, 29 | // tlb 30 | output [ 97:0] csr_tlb_out, 31 | input [ 97:0] csr_tlb_in, 32 | output [`WS_TO_ES_BUS_WD -1:0] ws_to_es_bus 33 | ); 34 | 35 | /* -------------- Handshaking signals -------------- */ 36 | 37 | reg ws_valid; 38 | wire ws_ready_go; 39 | 40 | /* ------------------- BUS ------------------- */ 41 | 42 | // MS to WS bus 43 | reg [`MS_TO_WS_BUS_WD -1:0] ms_to_ws_bus_r; 44 | 45 | wire ws_tlb_refetch; 46 | 47 | /* ------------------- CSR Interface ------------------- */ 48 | 49 | wire [13:0] ws_csr_num; 50 | wire ws_csr_re; 51 | wire [31:0] ws_csr_wmask; 52 | wire [31:0] ws_csr_wvalue; 53 | wire [31:0] ws_csr_rvalue; 54 | wire ws_csr_we; 55 | 56 | wire [31:0] counter_id; 57 | 58 | wire [31:0] ws_vaddr; 59 | wire [31:0] ws_final_result; 60 | 61 | wire ws_tlb_refetch; 62 | wire inst_tlbsrch; 63 | wire inst_tlbrd; 64 | wire inst_tlbwr; 65 | wire inst_tlbfill; 66 | wire inst_invtlb; 67 | wire [31:0] csr_asid_rvalue; 68 | wire [31:0] csr_tlbehi_rvalue; 69 | wire [31:0] csr_crmd_rvalue; 70 | wire [31:0] csr_dmw0_rvalue; 71 | wire [31:0] csr_dmw1_rvalue; 72 | wire [31:0] csr_tlbrentry_rvalue; 73 | 74 | /* ------------------- Regfile Interface ------------------- */ 75 | 76 | wire ws_gr_we; 77 | wire [ 4:0] ws_dest; 78 | wire [31:0] ws_pc; 79 | 80 | wire rf_we; 81 | wire [4 :0] rf_waddr; 82 | wire [31:0] rf_wdata; 83 | 84 | wire ws_inst_rdcntid; 85 | 86 | 87 | 88 | /* ------------------- Exceptions ------------------- */ 89 | 90 | wire ws_ertn_flush; 91 | wire fixed_ertn_flush; 92 | wire ws_esubcode; 93 | wire [ 5:0] ws_ecode; 94 | wire ws_ex; 95 | 96 | wire [31:0] ex_entry; 97 | wire [31:0] ex_era; 98 | wire has_int; 99 | 100 | wire es_tlb_refill_ex; 101 | wire refill_ex; 102 | /* ------------------- Debug Interface ------------------- */ 103 | 104 | // debug info generate 105 | assign debug_wb_pc = ws_pc; 106 | assign debug_wb_rf_wen = {4{rf_we}}; 107 | assign debug_wb_rf_wnum = ws_dest; 108 | assign debug_wb_rf_wdata = rf_wdata; 109 | 110 | 111 | /* -------------- Handshaking signals -------------- */ 112 | 113 | assign ws_ready_go = 1'b1; 114 | assign ws_allowin = !ws_valid || ws_ready_go; 115 | 116 | always @(posedge clk) begin 117 | if (reset | final_ex | fixed_ertn_flush) begin 118 | ws_valid <= 1'b0; 119 | end 120 | else if (ws_allowin) begin 121 | ws_valid <= ms_to_ws_valid; 122 | end 123 | end 124 | 125 | /* ------------------- BUS ------------------- */ 126 | 127 | always @(posedge clk) begin 128 | if (ms_to_ws_valid && ws_allowin) begin 129 | ms_to_ws_bus_r <= ms_to_ws_bus; 130 | end 131 | end 132 | 133 | assign {es_tlb_refill_ex, //198 134 | // s1_index , //201:198 135 | ws_tlb_refetch , //197 136 | inst_tlbsrch , //196 137 | inst_tlbrd , //195 138 | inst_tlbwr , //194 139 | inst_tlbfill , //193 140 | inst_invtlb , //192 141 | ws_inst_rdcntid, //191 142 | ws_vaddr , //190:159 143 | ws_ertn_flush , //158 144 | ws_esubcode , //157 145 | ws_ecode , //156:151 146 | ws_ex , //150 147 | ws_csr_re , //149 148 | ws_csr_num , //148:135 149 | ws_csr_wvalue , //134:103 150 | ws_csr_wmask , //102:71 151 | ws_csr_we , //70 152 | ws_gr_we , //69:69 153 | ws_dest , //68:64 154 | ws_final_result, //63:32 155 | ws_pc //31:0 156 | } = ms_to_ws_bus_r; 157 | 158 | // WS forward bus 159 | assign ws_forward = {(inst_tlbwr || inst_tlbrd || inst_tlbfill || inst_invtlb) && ws_valid , //123 160 | has_int , //122 161 | ex_era , //121:90 162 | ex_entry , //89:58 163 | final_ex , //57 164 | ws_csr_re , //56 165 | ws_csr_num , //55:42 166 | ws_csr_we , //41 167 | fixed_ertn_flush , //40 168 | ws_ex&ws_valid , //39 169 | ws_final_result, //38:7 170 | ws_dest , //6:2 171 | rf_we , //1 172 | ws_valid //0 173 | }; 174 | 175 | // WS to FS bus 176 | assign ws_to_fs_bus ={refill_ex, //260 177 | csr_tlbrentry_rvalue, //259:228 178 | csr_asid_rvalue, //227:196 179 | csr_crmd_rvalue, //195:164 180 | csr_dmw0_rvalue, //163:132 181 | csr_dmw1_rvalue, //131:100 182 | (inst_tlbwr || inst_tlbrd || inst_tlbfill || inst_invtlb) && ws_valid, //99 183 | ws_pc + 32'd4 , //98:67 184 | has_int , //66 185 | ex_era , //65:34 186 | ex_entry , //33:2 187 | final_ex , //1 188 | fixed_ertn_flush //0 189 | }; 190 | 191 | assign ws_to_es_bus ={csr_crmd_rvalue, 192 | csr_dmw0_rvalue, 193 | csr_dmw1_rvalue, 194 | csr_asid_rvalue, //63:32 195 | csr_tlbehi_rvalue//31:0 196 | }; 197 | 198 | /* ------------------- CSR Interface ------------------- */ 199 | 200 | // assign ws_vaddr = ws_final_result; 201 | 202 | regcsr u_regcsr( 203 | .clk (clk ), 204 | .reset (reset ), 205 | .ws_valid (ws_valid ), 206 | .csr_we (ws_csr_we ), 207 | .csr_num (ws_csr_num ), 208 | .csr_wmask (ws_csr_wmask ), 209 | .csr_wvalue (ws_csr_wvalue), 210 | .csr_rvalue (ws_csr_rvalue), 211 | .ertn_flush (ws_ertn_flush), 212 | .wb_ex (final_ex ), 213 | .refill_ex (refill_ex ), 214 | .wb_ecode (ws_ecode ), 215 | .wb_esubcode(ws_esubcode ), 216 | .wb_pc (ws_pc ), 217 | .ex_entry (ex_entry ), 218 | .ex_era (ex_era ), 219 | .has_int (has_int ), 220 | .wb_vaddr (ws_vaddr ), 221 | .counter (counter ), 222 | .counter_id (counter_id ), 223 | .csr_tlb_in (csr_tlb_in ), 224 | .csr_tlb_out(csr_tlb_out ), 225 | .csr_asid_rvalue (csr_asid_rvalue ), 226 | .csr_tlbehi_rvalue(csr_tlbehi_rvalue), 227 | .csr_crmd_rvalue (csr_crmd_rvalue ), 228 | .csr_dmw0_rvalue (csr_dmw0_rvalue ), 229 | .csr_dmw1_rvalue (csr_dmw1_rvalue ), 230 | .csr_tlbrentry_rvalue(csr_tlbrentry_rvalue) 231 | ); 232 | 233 | /* ------------------- Regfile Interface ------------------- */ 234 | 235 | assign rf_we = ws_gr_we && ws_valid && ~ws_ex && ~ws_tlb_refetch; 236 | assign rf_waddr = ws_dest; 237 | assign rf_wdata = {32{ws_csr_re}} & ws_csr_rvalue | 238 | // {32{ws_inst_rdcntid}} & counter_id | 239 | {32{~ws_csr_re}} & ws_final_result; 240 | 241 | assign ws_to_rf_bus = {rf_we , //37:37 242 | rf_waddr, //36:32 243 | rf_wdata //31:0 244 | }; 245 | 246 | /* ------------------- Exceptions ------------------- */ 247 | assign final_ex = ws_valid & (ws_ex | ws_ertn_flush | refill_ex); 248 | assign fixed_ertn_flush = (ws_ecode == `ECODE_ERT) && ws_valid; 249 | assign back_ertn_flush = fixed_ertn_flush; 250 | assign back_ex = final_ex; 251 | assign refill_ex = ws_valid & es_tlb_refill_ex; 252 | endmodule 253 | --------------------------------------------------------------------------------