From f3fe9b6eb5ff4eed3abc85f0fdc5f2e8e21d2d84 Mon Sep 17 00:00:00 2001 From: Class Account Date: Sun, 13 Dec 2020 16:42:15 -0800 Subject: [PATCH 1/5] creating new branch --- src/ALU.v | 1 + src/ALUdec.v | 1 + src/ASel.v | 1 + src/Adder.v | 2 + src/BSel.v | 2 + src/BrUn.v | 6 +- src/CSR.v | 2 +- src/Cache.v | 205 ++++++++++++++++++++-------------------------- src/LdSel.v | 3 +- src/LdSelMux.v | 2 +- src/MemRW.v | 1 + src/PCSel.v | 1 + src/StoreSel.v | 3 +- src/StoreSelMux.v | 3 +- src/WBSel.v | 3 +- src/WBSelMux.v | 3 +- syn.yml | 2 +- 17 files changed, 114 insertions(+), 127 deletions(-) diff --git a/src/ALU.v b/src/ALU.v index 702afe6..82228f7 100755 --- a/src/ALU.v +++ b/src/ALU.v @@ -17,6 +17,7 @@ module ALU( output reg [31:0] Out ); +initial Out = 32'd0; // Implement your ALU here, then delete this comment always @(*) begin case (ALUop) diff --git a/src/ALUdec.v b/src/ALUdec.v index e1517cf..4fa5c66 100755 --- a/src/ALUdec.v +++ b/src/ALUdec.v @@ -16,6 +16,7 @@ module ALUdec( output reg [3:0] ALUop ); +initial ALUop = 4'd0; // Implement your ALU decoder here, then delete this comment always @(*) begin case (opcode) diff --git a/src/ASel.v b/src/ASel.v index fc48243..285ca89 100644 --- a/src/ASel.v +++ b/src/ASel.v @@ -15,6 +15,7 @@ assign funct3 = inst[14:12]; wire uses_pc; assign uses_pc = (opcode == `OPC_AUIPC || opcode == `OPC_JAL || opcode == `OPC_BRANCH)? 1'b1: 1'b0; +initial ASelSignal = 1'b0; always @(*) begin case (uses_pc) 1'b1: ASelSignal = 1'b1; diff --git a/src/Adder.v b/src/Adder.v index ff5dcd2..e74f9ea 100644 --- a/src/Adder.v +++ b/src/Adder.v @@ -9,6 +9,8 @@ module Adder ( output reg [31:0] stage1_pc4 ); +initial stage1_pc4 = stage1_pc + 32'd4; + always @(*) begin case (PCAddSelect) 2'b01: stage1_pc4 = stage1_pc + stage1_imm; diff --git a/src/BSel.v b/src/BSel.v index 52dba61..fbe02c6 100644 --- a/src/BSel.v +++ b/src/BSel.v @@ -16,6 +16,8 @@ assign funct3 = inst[14:12]; wire uses_imm; assign uses_imm = (opcode == `OPC_ARI_ITYPE || opcode == `OPC_LUI || opcode == `OPC_AUIPC || opcode == `OPC_JAL || opcode == `OPC_JALR || opcode == `OPC_BRANCH || opcode == `OPC_STORE || opcode == `OPC_LOAD || opcode == `OPC_CSR)? 1'b1: 1'b0; +initial BSelSignal = 1'b0; + always @(*) begin case (uses_imm) 1'b1: BSelSignal = 1'b1; diff --git a/src/BrUn.v b/src/BrUn.v index 8650182..b067e97 100644 --- a/src/BrUn.v +++ b/src/BrUn.v @@ -8,6 +8,8 @@ module BrUn ( wire [6:0] opcode = inst[6:0]; wire [2:0] funct3 = inst[14:12]; +initial BrUnSignal = 1'b0; + always @(*) begin case(opcode) `OPC_BRANCH: begin @@ -16,10 +18,10 @@ always @(*) begin `FNC_BGEU: BrUnSignal = 1'b1; `FNC_BLT: BrUnSignal = 1'b0; `FNC_BGE: BrUnSignal = 1'b0; - default: BrUnSignal = 1'bx; + default: BrUnSignal = 1'b0; endcase end - default: BrUnSignal = 1'bx; + default: BrUnSignal = 1'b0; endcase end diff --git a/src/CSR.v b/src/CSR.v index 925a98e..9b5f835 100644 --- a/src/CSR.v +++ b/src/CSR.v @@ -12,7 +12,7 @@ module CSR ( always @(posedge clk) begin if (reset) begin - csr <= 32'dx; + csr <= 32'd0; end else begin if (CSRSel) begin csr <= rs1_to_csr; diff --git a/src/Cache.v b/src/Cache.v index 6662f5f..b4b91a2 100755 --- a/src/Cache.v +++ b/src/Cache.v @@ -17,14 +17,14 @@ module cache # input [CPU_WIDTH-1:0] cpu_req_data, // 32 bits // done input [3:0] cpu_req_write, // done - output reg cpu_resp_valid, // done + output cpu_resp_valid, // done output reg [CPU_WIDTH-1:0] cpu_resp_data, // done - output reg mem_req_valid, // done + output mem_req_valid, // done input mem_req_ready, // done output reg [WORD_ADDR_BITS-1:`ceilLog2(`MEM_DATA_BITS/CPU_WIDTH)] mem_req_addr, // done - output reg mem_req_rw, // done - output reg mem_req_data_valid, // done + output mem_req_rw, // done + output mem_req_data_valid, // done input mem_req_data_ready, // done output reg [`MEM_DATA_BITS-1:0] mem_req_data_bits, // done // byte level masking @@ -37,20 +37,23 @@ module cache # reg [2:0] STATE; reg [2:0] NEXT_STATE; -wire [2:0] IDLE; -assign IDLE = 3'b000; +//initial cpu_resp_valid = 1'b0; +// initial cpu_resp_data = {32{1'b0}}; +// initial mem_req_valid = 1'b0; +initial mem_req_addr = {28{1'b0}}; +// initial mem_req_rw = 1'b0; +// initial mem_req_data_valid = 1'b0; +initial mem_req_data_bits = {128{1'b0}}; +initial mem_req_data_mask = {16{1'b0}}; + +localparam IDLE = 3'b000; +localparam READ = 3'b001; +localparam MISS = 3'b010; +localparam WRITE = 3'b011; +localparam DONE = 3'b100; -wire [2:0] READ; -assign READ = 3'b001; - -wire [2:0] MISS; -assign MISS = 3'b010; - -wire [2:0] WRITE; -assign WRITE = 3'b011; - -wire [2:0] DONE; -assign DONE = 3'b100; +initial STATE = IDLE; +initial NEXT_STATE = IDLE; //-----------------------------------// @@ -59,26 +62,41 @@ reg [22:0] tag; reg [2:0] index; reg [3:0] offset; -reg [3:0] tag_valid_addr; +initial original_addr = 30'd0; +initial tag = 23'd0; +initial index = 3'd0; +initial offset = 4'd0; + +wire [3:0] tag_valid_addr; reg [5:0] data_addr; reg write_enable_tag_valid; reg write_enable_data; +// initial tag_valid_addr = 4'd0; +initial data_addr = 6'd0; +initial write_enable_tag_valid = 1'b1; +initial write_enable_data = 1'b1; + wire [31:0] tag_valid_out; wire [127:0] data_out; reg [31:0] tag_valid_in; reg [127:0] data_in; +initial tag_valid_in = 32'd0; +initial data_in = 128'd0; + reg [31:0] original_data; reg [3:0] original_write; +initial original_data = 32'd0; +initial original_write = 4'd0; + reg [31:0] mask; -initial STATE = IDLE; -initial NEXT_STATE = IDLE; +initial mask = 32'd0; -integer clk_counter; +integer clk_counter = 0; localparam WORDS = `MEM_DATA_BITS/CPU_WIDTH; wire [`ceilLog2(WORDS)-1:0] lower_addr; @@ -86,6 +104,21 @@ assign lower_addr = original_addr[`ceilLog2(WORDS)-1:0]; assign cpu_req_ready = (STATE == IDLE || STATE == WRITE)? 1'b1 : 1'b0; +assign cpu_resp_valid = (STATE == READ && tag_valid_out[22:0] == tag && tag_valid_out[31])? 1'b1: 1'b0; +assign mem_req_valid = ((STATE == IDLE && cpu_req_valid && cpu_req_write != 4'b0000) + || (STATE == READ && !(tag_valid_out[22:0] == tag && tag_valid_out[31]) && mem_req_ready))? 1'b1: 1'b0; +assign mem_req_rw = (STATE == IDLE && cpu_req_valid && cpu_req_write != 4'b0000)? 1'b1: 1'b0; +assign mem_req_data_valid = (STATE == IDLE && cpu_req_valid && cpu_req_write != 4'b0000)? 1'b1: 1'b0; + +assign tag_valid_addr = {1'b0, index}; + +// assign cpu_resp_data = (STATE == READ && tag_valid_out[22:0] == tag && tag_valid_out[31])? +// (offset[1:0] == 2'b00)? data_out[31:0]: +// (offset[1:0] == 2'b01)? data_out[63:32]: +// (offset[1:0] == 2'b10)? data_out[95:64]: +// (offset[1:0] == 2'b11)? data_out[127:96]: 32'd0 +// : 32'd0; + // You should include a separate SRAM per way for the tags. Implement the valid bits as part of the tag SRAM. SRAM2RW16x32 tag_valid_sram ( .CE1(clk), // clock edge (clock signal) @@ -105,13 +138,6 @@ SRAM2RW16x32 tag_valid_sram ( .O2() ); - -//////////////////////////////////////////////////// -// DONT FORGET TO CHANGE NECESSARY OUTPUTS TO REG // -//////////////////////////////////////////////////// - - -// You should include a SRAM per way for data. SRAM1RW64x128 data_sram ( .CE(clk), .WEB(write_enable_data), @@ -123,12 +149,10 @@ SRAM1RW64x128 data_sram ( .O(data_out) ); -// mealy state machine? -// sequential logic always @(posedge clk) begin if (reset) begin STATE <= IDLE; - //NEXT_STATE <= IDLE; + NEXT_STATE <= IDLE; end else begin STATE <= NEXT_STATE; end @@ -147,41 +171,37 @@ always @(*) begin case (STATE) IDLE: begin if (cpu_req_valid) begin - cpu_resp_valid = 1'b0; - mem_req_valid = 1'b0; - mem_req_data_valid = 1'b0; + + //cpu_resp_valid = 1'b0; + // mem_req_valid = 1'b0; + // mem_req_data_valid = 1'b0; - // I added this - // cpu_req_ready = 1'b1; - mem_req_rw = 1'b0; + // mem_req_rw = 1'b0; - original_data = cpu_req_data; - original_write = cpu_req_write; + original_data = cpu_req_data; + original_write = cpu_req_write; - original_addr = cpu_req_addr; // 30 bits - tag = cpu_req_addr[29:7]; // 23 bits - index = cpu_req_addr[6:4]; // 3 bits - offset = cpu_req_addr[3:0]; // 4 bits + original_addr = cpu_req_addr; // 30 bits + tag = cpu_req_addr[29:7]; // 23 bits + index = cpu_req_addr[6:4]; // 3 bits + offset = cpu_req_addr[3:0]; // 4 bits - tag_valid_addr = {{1{1'b0}}, index}; // 4 bits - data_addr = (index*4) + offset[3:2]; // 6 bits + // tag_valid_addr = {{1{1'b0}}, index}; // 4 bits + data_addr = (index*4) + offset[3:2]; // 6 bits - write_enable_tag_valid = 1'b1; // SRAM -> READ - write_enable_data = 1'b1; // SRAM -> READ + write_enable_tag_valid = 1'b1; // SRAM -> READ + write_enable_data = 1'b1; // SRAM -> READ - mask = {{8{cpu_req_write[3]}}, - {8{cpu_req_write[2]}}, - {8{cpu_req_write[1]}}, - {8{cpu_req_write[0]}}}; + mask = {{8{cpu_req_write[3]}}, + {8{cpu_req_write[2]}}, + {8{cpu_req_write[1]}}, + {8{cpu_req_write[0]}}}; if (cpu_req_write == 4'b0000) begin NEXT_STATE = READ; end else if (cpu_req_write != 4'b0000) begin NEXT_STATE = WRITE; - // mem_req_addr = original_addr[29:2]; - //mem_req_rw = 1'b1; - // mem_req_valid = 1'b1; - mem_req_rw = 1'b1; + // mem_req_rw = 1'b1; case (offset[1:0]) 2'b11: begin @@ -205,12 +225,12 @@ always @(*) begin end endcase - mem_req_data_valid = 1'b1; + // mem_req_data_valid = 1'b1; mem_req_addr = original_addr[29:2]; - mem_req_valid = 1'b1; // it means the address provided above is valid + // mem_req_valid = 1'b1; // it means the address provided above is valid end - end + end end READ: begin @@ -221,17 +241,17 @@ always @(*) begin 2'b10: cpu_resp_data = data_out[95:64]; 2'b11: cpu_resp_data = data_out[127:96]; endcase - cpu_resp_valid = 1'b1; + //cpu_resp_valid = 1'b1; NEXT_STATE = IDLE; end else begin if (mem_req_ready) begin write_enable_tag_valid = 1'b0; // SRAM -> WRITE mem_req_addr = original_addr[29:2]; - mem_req_valid = 1'b1; - mem_req_rw = 1'b0; + // mem_req_valid = 1'b1; + // mem_req_rw = 1'b0; - tag_valid_addr = {{1{1'b0}}, index}; + // tag_valid_addr = {{1{1'b0}}, index}; tag_valid_in = {1'b1, {8{1'b0}}, tag}; NEXT_STATE = MISS; @@ -247,87 +267,38 @@ always @(*) begin data_in = mem_resp_data; data_addr = (index*4) + clk_counter; end -//count = count + 1; - - //$display("COUNT: %d AT CLK: %d", clk_counter, clk_counter); if (clk_counter < 3) begin - //write_enable_data = 1'b0; - - //data_in = mem_resp_data; - //data_addr = (index*4) + clk_counter; - NEXT_STATE = MISS; mem_req_addr = original_addr[29:2] + clk_counter + 1; - //mem_req_addr = mem_req_addr + 1; - //$display("MEM_REQ_ADDR: %b", mem_req_addr); end else if (clk_counter == 3) begin - // done = 1'b1; - // added the following//////////// - mem_req_valid = 1'b0; + // mem_req_valid = 1'b0; NEXT_STATE = DONE; - //end else if (clk_counter == 3) begin - // NEXT_STATE = MISS; - end + end + end else if (!mem_resp_valid) begin NEXT_STATE = MISS; end end + DONE: begin - //if (done) begin - tag_valid_addr = {{1{1'b0}}, index}; + // tag_valid_addr = {{1{1'b0}}, index}; write_enable_tag_valid = 1'b1; write_enable_data = 1'b1; // SRAM -> READ data_addr = (index*4) + offset[3:2]; NEXT_STATE = READ; - //end - - end + WRITE: begin - //mem_req_data_ready && mem_req_ready - //if (mem_req_data_ready) begin if (tag_valid_out[22:0] == tag && tag_valid_out[31] == 1'b1) begin // this is for SRAM write_enable_data = 1'b0; data_in = (data_out & ~({{`MEM_DATA_BITS-CPU_WIDTH{1'b0}}, mask} << CPU_WIDTH*lower_addr)) | ((cpu_req_data & mask) << CPU_WIDTH*lower_addr); data_addr = (index*4) + offset[3:2]; end - - // mem_req_rw = 1'b1; - - // case (offset[1:0]) - // 2'b11: begin - // mem_req_data_mask = {original_write, {12{1'b0}}}; - // mem_req_data_bits = {original_data, 96'd0}; - // end - - // 2'b10: begin - // mem_req_data_mask = {4'd0, original_write, 8'd0}; - // mem_req_data_bits = {32'd0, original_data, 64'd0}; - // end - - // 2'b01: begin - // mem_req_data_mask = {8'd0, original_write, 4'd0}; - // mem_req_data_bits = {64'd0, original_data, 32'd0}; - // end - - // 2'b00: begin - // mem_req_data_mask = {12'd0, original_write}; - // mem_req_data_bits = {96'd0, original_data}; - // end - // endcase - - // mem_req_data_valid = 1'b1; - - // mem_req_addr = original_addr[29:2]; - // mem_req_valid = 1'b1; // it means the address provided above is valid NEXT_STATE = IDLE; - // end else begin - // NEXT_STATE = WRITE; - //end end endcase end diff --git a/src/LdSel.v b/src/LdSel.v index 5dc0077..51a51d4 100644 --- a/src/LdSel.v +++ b/src/LdSel.v @@ -21,9 +21,10 @@ always @(*) begin `FNC_LW: LdSelect = 3'b010; `FNC_LBU: LdSelect = 3'b011; `FNC_LHU: LdSelect = 3'b100; + default: LdSelect = 3'b111; endcase end - default: LdSelect = 3'bxxx; + default: LdSelect = 3'b111; endcase end diff --git a/src/LdSelMux.v b/src/LdSelMux.v index 110600d..8507e3b 100644 --- a/src/LdSelMux.v +++ b/src/LdSelMux.v @@ -102,7 +102,7 @@ always @(*) begin 3'b010: wb_dmem = raw_dmem; - default: wb_dmem = 32'dx; + default: wb_dmem = 32'd0; endcase end diff --git a/src/MemRW.v b/src/MemRW.v index 3f6049d..7fff058 100644 --- a/src/MemRW.v +++ b/src/MemRW.v @@ -39,6 +39,7 @@ always @(*) begin endcase end `FNC_SW: MemRWSelect = 4'b1111; + default: MemRWSelect = 4'b0000; endcase end default: MemRWSelect = 4'b0000; diff --git a/src/PCSel.v b/src/PCSel.v index 4553d61..c7d4cd8 100644 --- a/src/PCSel.v +++ b/src/PCSel.v @@ -96,6 +96,7 @@ always @(*) begin take_branch = 1'b0; end end + default: take_branch = 1'b0; endcase end default: take_branch = 1'b0; diff --git a/src/StoreSel.v b/src/StoreSel.v index 1234b5b..a8c7ec5 100644 --- a/src/StoreSel.v +++ b/src/StoreSel.v @@ -24,9 +24,10 @@ always @(*) begin `FNC_SB: StoreSelect = 2'b00; `FNC_SH: StoreSelect = 2'b01; `FNC_SW: StoreSelect = 2'b10; + default: StoreSelect = 2'b11; endcase end - default: StoreSelect = 2'bxx; + default: StoreSelect = 2'b11; endcase end diff --git a/src/StoreSelMux.v b/src/StoreSelMux.v index 2948c9e..0b427bd 100644 --- a/src/StoreSelMux.v +++ b/src/StoreSelMux.v @@ -10,6 +10,7 @@ module StoreSelMux ( reg [31:0] shift_extended; +initial dmem_write_data = 32'd0; always @(*) begin case (StoreSel) 2'b01: // SH @@ -40,7 +41,7 @@ always @(*) begin 2'b10: dmem_write_data = stage2_rs2_data; // SW - default: dmem_write_data = 32'dx; // idc + default: dmem_write_data = 32'd0; // idc endcase end diff --git a/src/WBSel.v b/src/WBSel.v index 2d2c4a7..0fdb876 100644 --- a/src/WBSel.v +++ b/src/WBSel.v @@ -15,6 +15,7 @@ module WBSel ( wire [6:0] opcode; assign opcode = stage3_inst[6:0]; +initial WBSelect = 2'b11; always @(*) begin case (opcode) `OPC_LOAD: WBSelect = 2'b00; @@ -24,7 +25,7 @@ always @(*) begin `OPC_LUI: WBSelect = 2'b01; `OPC_JALR: WBSelect = 2'b10; `OPC_JAL: WBSelect = 2'b10; - default: WBSelect = 2'bxx; + default: WBSelect = 2'b11; endcase end diff --git a/src/WBSelMux.v b/src/WBSelMux.v index 555c51e..e106016 100644 --- a/src/WBSelMux.v +++ b/src/WBSelMux.v @@ -9,12 +9,13 @@ module WBSelMux ( output reg [31:0] wb_data ); +initial wb_data = 32'd0; always @(*) begin case (WBSel) 2'b00: wb_data = wb_dmem; 2'b01: wb_data = stage3_alu_out; 2'b10: wb_data = stage3_pc4; - default: wb_data = 32'dx; + default: wb_data = 32'd0; endcase end diff --git a/syn.yml b/syn.yml index e3bf31e..0d0a026 100755 --- a/syn.yml +++ b/syn.yml @@ -16,7 +16,7 @@ verilogSrc: &VERILOG_SRC - "src/Riscv151.v" - "src/Memory151.v" # - "src/ExtMemModel.v" - - "src/no_cache_mem.v" + # - "src/no_cache_mem.v" - "src/Cache.v" - "src/riscv_top.v" - "src/riscv_arbiter.v" From 784a5556a966c90c5d959fb0ac07516546ce7000 Mon Sep 17 00:00:00 2001 From: Class Account Date: Mon, 14 Dec 2020 13:09:19 -0800 Subject: [PATCH 2/5] created new cache --- src/Cache.v | 494 +++++++++++++++++++++++++++------------------------- 1 file changed, 259 insertions(+), 235 deletions(-) diff --git a/src/Cache.v b/src/Cache.v index b4b91a2..ab314eb 100755 --- a/src/Cache.v +++ b/src/Cache.v @@ -8,126 +8,88 @@ module cache # parameter WORD_ADDR_BITS = `CPU_ADDR_BITS-`ceilLog2(`CPU_INST_BITS/8) // 30 bits ) ( - input clk, // done - input reset, // done - - input cpu_req_valid, // done - output cpu_req_ready, // done - input [WORD_ADDR_BITS-1:0] cpu_req_addr, // 30 bits // done - input [CPU_WIDTH-1:0] cpu_req_data, // 32 bits // done - input [3:0] cpu_req_write, // done - - output cpu_resp_valid, // done - output reg [CPU_WIDTH-1:0] cpu_resp_data, // done - - output mem_req_valid, // done - input mem_req_ready, // done - output reg [WORD_ADDR_BITS-1:`ceilLog2(`MEM_DATA_BITS/CPU_WIDTH)] mem_req_addr, // done - output mem_req_rw, // done - output mem_req_data_valid, // done - input mem_req_data_ready, // done - output reg [`MEM_DATA_BITS-1:0] mem_req_data_bits, // done + input clk, + input reset, + + input cpu_req_valid, + output reg cpu_req_ready, + input [WORD_ADDR_BITS-1:0] cpu_req_addr, // 30 bits + input [CPU_WIDTH-1:0] cpu_req_data, // 32 bits + input [3:0] cpu_req_write, + + output reg cpu_resp_valid, + output reg [CPU_WIDTH-1:0] cpu_resp_data, + + output reg mem_req_valid, + input mem_req_ready, + output reg [WORD_ADDR_BITS-1:`ceilLog2(`MEM_DATA_BITS/CPU_WIDTH)] mem_req_addr, // 28 bits + output reg mem_req_rw, + output reg mem_req_data_valid, + input mem_req_data_ready, + output reg [`MEM_DATA_BITS-1:0] mem_req_data_bits, // byte level masking - output reg [(`MEM_DATA_BITS/8)-1:0] mem_req_data_mask, // done + output reg [(`MEM_DATA_BITS/8)-1:0] mem_req_data_mask, - input mem_resp_valid, // done - input [`MEM_DATA_BITS-1:0] mem_resp_data // done + input mem_resp_valid, + input [`MEM_DATA_BITS-1:0] mem_resp_data ); -reg [2:0] STATE; -reg [2:0] NEXT_STATE; - -//initial cpu_resp_valid = 1'b0; -// initial cpu_resp_data = {32{1'b0}}; -// initial mem_req_valid = 1'b0; -initial mem_req_addr = {28{1'b0}}; -// initial mem_req_rw = 1'b0; -// initial mem_req_data_valid = 1'b0; -initial mem_req_data_bits = {128{1'b0}}; -initial mem_req_data_mask = {16{1'b0}}; - +// States info localparam IDLE = 3'b000; -localparam READ = 3'b001; -localparam MISS = 3'b010; -localparam WRITE = 3'b011; -localparam DONE = 3'b100; +localparam READ = 3'b001; // Read tag +localparam MISS0 = 3'b010; +localparam MISS1 = 3'b011; +localparam MISS2 = 3'b100; +localparam MISS3 = 3'b101; +localparam WRITE = 3'b110; +localparam DONE = 3'b111; + +// mask for writing to cache +localparam WORDS = `MEM_DATA_BITS/CPU_WIDTH; +wire [`ceilLog2(WORDS)-1:0] lower_addr; +assign lower_addr = cpu_req_addr[`ceilLog2(WORDS)-1:0]; +// reg for FSM +reg [2:0] STATE; +reg [2:0] NEXT_STATE; initial STATE = IDLE; initial NEXT_STATE = IDLE; -//-----------------------------------// - +// reg for input cpu_req_addr reg [29:0] original_addr; -reg [22:0] tag; -reg [2:0] index; -reg [3:0] offset; - -initial original_addr = 30'd0; -initial tag = 23'd0; -initial index = 3'd0; -initial offset = 4'd0; - -wire [3:0] tag_valid_addr; -reg [5:0] data_addr; -reg write_enable_tag_valid; -reg write_enable_data; - -// initial tag_valid_addr = 4'd0; -initial data_addr = 6'd0; -initial write_enable_tag_valid = 1'b1; -initial write_enable_data = 1'b1; +// tag, index and offset fields of cpu_req_addr +wire [21:0] tag; +wire [3:0] index; +wire [3:0] offset; +assign tag = original_addr[29:8]; +assign index = original_addr[7:4]; +assign offset = original_addr[3:0]; + +// input and ouput reg/wire for tag_valid_sram +reg write_en_tag_valid; +reg [3:0] tag_valid_addr; // 4-bit addr to represent 16 rows +reg [31:0] tag_valid_in; wire [31:0] tag_valid_out; -wire [127:0] data_out; -reg [31:0] tag_valid_in; +// input and output reg/wire for data_sram +reg write_en_data; +reg [5:0] data_addr; reg [127:0] data_in; +wire [127:0] data_out; -initial tag_valid_in = 32'd0; -initial data_in = 128'd0; - -reg [31:0] original_data; -reg [3:0] original_write; - -initial original_data = 32'd0; -initial original_write = 4'd0; - +// reg for mask reg [31:0] mask; -initial mask = 32'd0; - -integer clk_counter = 0; - -localparam WORDS = `MEM_DATA_BITS/CPU_WIDTH; -wire [`ceilLog2(WORDS)-1:0] lower_addr; -assign lower_addr = original_addr[`ceilLog2(WORDS)-1:0]; - -assign cpu_req_ready = (STATE == IDLE || STATE == WRITE)? 1'b1 : 1'b0; - -assign cpu_resp_valid = (STATE == READ && tag_valid_out[22:0] == tag && tag_valid_out[31])? 1'b1: 1'b0; -assign mem_req_valid = ((STATE == IDLE && cpu_req_valid && cpu_req_write != 4'b0000) - || (STATE == READ && !(tag_valid_out[22:0] == tag && tag_valid_out[31]) && mem_req_ready))? 1'b1: 1'b0; -assign mem_req_rw = (STATE == IDLE && cpu_req_valid && cpu_req_write != 4'b0000)? 1'b1: 1'b0; -assign mem_req_data_valid = (STATE == IDLE && cpu_req_valid && cpu_req_write != 4'b0000)? 1'b1: 1'b0; - -assign tag_valid_addr = {1'b0, index}; - -// assign cpu_resp_data = (STATE == READ && tag_valid_out[22:0] == tag && tag_valid_out[31])? -// (offset[1:0] == 2'b00)? data_out[31:0]: -// (offset[1:0] == 2'b01)? data_out[63:32]: -// (offset[1:0] == 2'b10)? data_out[95:64]: -// (offset[1:0] == 2'b11)? data_out[127:96]: 32'd0 -// : 32'd0; -// You should include a separate SRAM per way for the tags. Implement the valid bits as part of the tag SRAM. SRAM2RW16x32 tag_valid_sram ( - .CE1(clk), // clock edge (clock signal) + .CE1(clk), .CE2(), - .WEB1(write_enable_tag_valid), // Write Enable Bar (HIGH: Read, LOW: Write) + .WEB1(write_en_tag_valid), // Write Enable Bar (HIGH: Read, LOW: Write) .WEB2(), - .OEB1(1'b0), // Output Enable Bar (always tie to LOW) + .OEB1(1'b0), .OEB2(), - .CSB1(1'b0), // Chip Select Bar (always tie to LOW) + .CSB1(1'b0), .CSB2(), .A1(tag_valid_addr), // Address pin @@ -140,7 +102,7 @@ SRAM2RW16x32 tag_valid_sram ( SRAM1RW64x128 data_sram ( .CE(clk), - .WEB(write_enable_data), + .WEB(write_en_data), // Write Enable Bar (HIGH: Read, LOW: Write) .OEB(1'b0), .CSB(1'b0), @@ -152,155 +114,217 @@ SRAM1RW64x128 data_sram ( always @(posedge clk) begin if (reset) begin STATE <= IDLE; - NEXT_STATE <= IDLE; + // NEXT_STATE <= IDLE; end else begin STATE <= NEXT_STATE; end end -always @(posedge clk) begin - if (reset || (STATE == READ && NEXT_STATE == MISS)) begin - clk_counter <= 0; - end else begin - clk_counter <= clk_counter + 1; - end -end - -// combinational logic +// combinational always @(*) begin - case (STATE) - IDLE: begin - if (cpu_req_valid) begin - - //cpu_resp_valid = 1'b0; - // mem_req_valid = 1'b0; - // mem_req_data_valid = 1'b0; - // mem_req_rw = 1'b0; - - original_data = cpu_req_data; - original_write = cpu_req_write; - - original_addr = cpu_req_addr; // 30 bits - tag = cpu_req_addr[29:7]; // 23 bits - index = cpu_req_addr[6:4]; // 3 bits - offset = cpu_req_addr[3:0]; // 4 bits - - // tag_valid_addr = {{1{1'b0}}, index}; // 4 bits - data_addr = (index*4) + offset[3:2]; // 6 bits - - write_enable_tag_valid = 1'b1; // SRAM -> READ - write_enable_data = 1'b1; // SRAM -> READ - - mask = {{8{cpu_req_write[3]}}, - {8{cpu_req_write[2]}}, - {8{cpu_req_write[1]}}, - {8{cpu_req_write[0]}}}; - - if (cpu_req_write == 4'b0000) begin - NEXT_STATE = READ; - end else if (cpu_req_write != 4'b0000) begin - NEXT_STATE = WRITE; - // mem_req_rw = 1'b1; - - case (offset[1:0]) - 2'b11: begin - mem_req_data_mask = {original_write, {12{1'b0}}}; - mem_req_data_bits = {original_data, 96'd0}; - end - - 2'b10: begin - mem_req_data_mask = {4'd0, original_write, 8'd0}; - mem_req_data_bits = {32'd0, original_data, 64'd0}; - end - - 2'b01: begin - mem_req_data_mask = {8'd0, original_write, 4'd0}; - mem_req_data_bits = {64'd0, original_data, 32'd0}; - end - - 2'b00: begin - mem_req_data_mask = {12'd0, original_write}; - mem_req_data_bits = {96'd0, original_data}; - end - endcase - - // mem_req_data_valid = 1'b1; - - mem_req_addr = original_addr[29:2]; - // mem_req_valid = 1'b1; // it means the address provided above is valid - end - end - end - - READ: begin - if (tag_valid_out[22:0] == tag && tag_valid_out[31]) begin - case (offset[1:0]) - 2'b00: cpu_resp_data = data_out[31:0]; - 2'b01: cpu_resp_data = data_out[63:32]; - 2'b10: cpu_resp_data = data_out[95:64]; - 2'b11: cpu_resp_data = data_out[127:96]; - endcase - //cpu_resp_valid = 1'b1; - NEXT_STATE = IDLE; - end else begin - if (mem_req_ready) begin - write_enable_tag_valid = 1'b0; // SRAM -> WRITE - - mem_req_addr = original_addr[29:2]; - // mem_req_valid = 1'b1; - // mem_req_rw = 1'b0; - - // tag_valid_addr = {{1{1'b0}}, index}; - tag_valid_in = {1'b1, {8{1'b0}}, tag}; - - NEXT_STATE = MISS; - end - end - end - - MISS: begin - if (mem_resp_valid) begin - if (clk_counter < 4) begin - write_enable_data = 1'b0; // SRAM -> WRITE - - data_in = mem_resp_data; - data_addr = (index*4) + clk_counter; - end + // default values for all signals + NEXT_STATE = STATE; + + // read tag by default + write_en_tag_valid = 1'b1; + // index for tag_valid_sram + tag_valid_addr = index; + + // default input data for tag_valid_sram + tag_valid_in = {1'b1, {9{1'b0}}, tag}; + + // read data by default + write_en_data = 1'b1; + // index for data_sram + data_addr = index * 4 + offset[3:2]; + + // default mask for writing to sram + mask = {{8{cpu_req_write[3]}}, + {8{cpu_req_write[2]}}, + {8{cpu_req_write[1]}}, + {8{cpu_req_write[0]}}}; + // default input data for data_sram + data_in = (data_out & ~({{`MEM_DATA_BITS-CPU_WIDTH{1'b0}}, mask} << CPU_WIDTH*lower_addr)) + | ((cpu_req_data & mask) << CPU_WIDTH*lower_addr); + + + + // assign cpu_resp_data + cpu_resp_data = cpu_resp_data; + // case (offset[1:0]) + // 2'b00: cpu_resp_data = data_out[31:0]; + // 2'b01: cpu_resp_data = data_out[63:32]; + // 2'b10: cpu_resp_data = data_out[95:64]; + // 2'b11: cpu_resp_data = data_out[127:96]; + // endcase + + // default ext memory request address + mem_req_addr = cpu_req_addr[29:2]; + // read data from ext mem by default + mem_req_rw = 1'b0; + + // default cpu control bits + cpu_req_ready = 1'b0; + cpu_resp_valid = 1'b0; + + // default ext mem control bits + mem_req_valid = 1'b0; + mem_req_data_valid = 1'b0; + + // assign mem_req_data_bits and mem_req_data_mask + case (offset[1:0]) + 2'b00: + begin + mem_req_data_bits = {96'd0, cpu_req_data}; + mem_req_data_mask = {12'd0, cpu_req_write}; + end + + 2'b01: + begin + mem_req_data_bits = {64'd0, cpu_req_data, 32'd0}; + mem_req_data_mask = {8'd0, cpu_req_write, 4'd0}; + end + + 2'b10: + begin + mem_req_data_bits = {32'd0, cpu_req_data, 64'd0}; + mem_req_data_mask = {4'd0, cpu_req_write, 8'd0}; + end + + 2'b11: + begin + mem_req_data_bits = {cpu_req_data, 96'd0}; + mem_req_data_mask = {cpu_req_write, 12'd0}; + end + endcase - if (clk_counter < 3) begin - NEXT_STATE = MISS; - mem_req_addr = original_addr[29:2] + clk_counter + 1; - end else if (clk_counter == 3) begin - // added the following//////////// - // mem_req_valid = 1'b0; + //assign - NEXT_STATE = DONE; - end - end else if (!mem_resp_valid) begin - NEXT_STATE = MISS; - end + case (STATE) + IDLE: + begin + cpu_req_ready = 1'b1; + original_addr = cpu_req_addr; + if (cpu_req_valid) begin + + if (cpu_req_write == 4'b0000) begin + NEXT_STATE = READ; + end else if (mem_req_ready) begin + NEXT_STATE = WRITE; + mem_req_rw = 1'b1; + mem_req_data_valid = 1'b1; + mem_req_valid = 1'b1; end - DONE: begin - // tag_valid_addr = {{1{1'b0}}, index}; - write_enable_tag_valid = 1'b1; - write_enable_data = 1'b1; // SRAM -> READ - data_addr = (index*4) + offset[3:2]; - NEXT_STATE = READ; - end + end + + end + + READ: + begin + + if (tag_valid_out[21:0] == tag && tag_valid_out[31]) begin + case (offset[1:0]) + 2'b00: cpu_resp_data = data_out[31:0]; + 2'b01: cpu_resp_data = data_out[63:32]; + 2'b10: cpu_resp_data = data_out[95:64]; + 2'b11: cpu_resp_data = data_out[127:96]; + endcase + cpu_resp_valid = 1'b1; + data_addr = index * 4 + offset[3:2]; + NEXT_STATE = IDLE; + end else begin + write_en_tag_valid = 1'b0; + tag_valid_addr = index; + mem_req_valid = 1'b1; + NEXT_STATE = MISS0; + end + + end + + MISS0: + begin + + if (mem_resp_valid) begin + + data_addr = index * 4; + data_in = mem_resp_data; + write_en_data = 1'b0; + + mem_req_addr = cpu_req_addr[29:2] + 1; + mem_req_valid = 1'b1; + NEXT_STATE = MISS1; + end + + end + + MISS1: + begin + + if (mem_resp_valid) begin + data_addr = index * 4 + 1; + data_in = mem_resp_data; + write_en_data = 1'b0; + + mem_req_addr = cpu_req_addr[29:2] + 2; + mem_req_valid = 1'b1; + NEXT_STATE = MISS2; + end + + end + + MISS2: + begin + + if (mem_resp_valid) begin + data_addr = index * 4 + 2; + data_in = mem_resp_data; + write_en_data = 1'b0; + + mem_req_addr = cpu_req_addr[29:2] + 3; + mem_req_valid = 1'b1; + NEXT_STATE = MISS3; + end + + end + + MISS3: + begin + + if (mem_resp_valid) begin + data_addr = index * 4 + 3; + data_in = mem_resp_data; + write_en_data = 1'b0; + mem_req_valid = 1'b0; + NEXT_STATE = DONE; + end + + end + + DONE: + begin + + NEXT_STATE = READ; + end + + WRITE: + begin + mem_req_data_valid = 1'b1; + cpu_req_ready = 1'b1; + + if (tag_valid_out[21:0] == tag && tag_valid_out[31]) begin + write_en_data = 1'b0; + end + + NEXT_STATE = IDLE; + + end - WRITE: begin - if (tag_valid_out[22:0] == tag && tag_valid_out[31] == 1'b1) begin - // this is for SRAM - write_enable_data = 1'b0; - data_in = (data_out & ~({{`MEM_DATA_BITS-CPU_WIDTH{1'b0}}, mask} << CPU_WIDTH*lower_addr)) | ((cpu_req_data & mask) << CPU_WIDTH*lower_addr); - data_addr = (index*4) + offset[3:2]; - end - NEXT_STATE = IDLE; - end endcase + + end -endmodule +endmodule \ No newline at end of file From 6c81e41c8fde0b0113ea7ff6e91acbc963b2005d Mon Sep 17 00:00:00 2001 From: Class Account Date: Mon, 14 Dec 2020 14:59:39 -0800 Subject: [PATCH 3/5] updated the new cache --- src/Cache.v | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/src/Cache.v b/src/Cache.v index ab314eb..ce2df83 100755 --- a/src/Cache.v +++ b/src/Cache.v @@ -57,13 +57,15 @@ initial NEXT_STATE = IDLE; // reg for input cpu_req_addr reg [29:0] original_addr; +reg [3:0] original_write; +reg[31:0] original_data; // tag, index and offset fields of cpu_req_addr wire [21:0] tag; wire [3:0] index; wire [3:0] offset; assign tag = original_addr[29:8]; -assign index = original_addr[7:4]; +assign index = original_addr[7:4]; assign offset = original_addr[3:0]; // input and ouput reg/wire for tag_valid_sram @@ -140,13 +142,13 @@ always @(*) begin data_addr = index * 4 + offset[3:2]; // default mask for writing to sram - mask = {{8{cpu_req_write[3]}}, - {8{cpu_req_write[2]}}, - {8{cpu_req_write[1]}}, - {8{cpu_req_write[0]}}}; + mask = {{8{original_write[3]}}, + {8{original_write[2]}}, + {8{original_write[1]}}, + {8{original_write[0]}}}; // default input data for data_sram data_in = (data_out & ~({{`MEM_DATA_BITS-CPU_WIDTH{1'b0}}, mask} << CPU_WIDTH*lower_addr)) - | ((cpu_req_data & mask) << CPU_WIDTH*lower_addr); + | ((original_data & mask) << CPU_WIDTH*lower_addr); @@ -160,7 +162,7 @@ always @(*) begin // endcase // default ext memory request address - mem_req_addr = cpu_req_addr[29:2]; + mem_req_addr = original_addr[29:2]; // read data from ext mem by default mem_req_rw = 1'b0; @@ -176,40 +178,45 @@ always @(*) begin case (offset[1:0]) 2'b00: begin - mem_req_data_bits = {96'd0, cpu_req_data}; - mem_req_data_mask = {12'd0, cpu_req_write}; + mem_req_data_bits = {96'd0, original_data}; + mem_req_data_mask = {12'd0, original_write}; end 2'b01: begin - mem_req_data_bits = {64'd0, cpu_req_data, 32'd0}; - mem_req_data_mask = {8'd0, cpu_req_write, 4'd0}; + mem_req_data_bits = {64'd0, original_data, 32'd0}; + mem_req_data_mask = {8'd0, original_write, 4'd0}; end 2'b10: begin - mem_req_data_bits = {32'd0, cpu_req_data, 64'd0}; - mem_req_data_mask = {4'd0, cpu_req_write, 8'd0}; + mem_req_data_bits = {32'd0, original_data, 64'd0}; + mem_req_data_mask = {4'd0, original_write, 8'd0}; end 2'b11: begin - mem_req_data_bits = {cpu_req_data, 96'd0}; - mem_req_data_mask = {cpu_req_write, 12'd0}; + mem_req_data_bits = {original_data, 96'd0}; + mem_req_data_mask = {original_write, 12'd0}; end endcase - //assign + original_addr = original_addr; + original_write = original_write; + original_data = original_data; case (STATE) IDLE: begin cpu_req_ready = 1'b1; - original_addr = cpu_req_addr; + if (cpu_req_valid) begin + original_addr = cpu_req_addr; + original_write = cpu_req_write; + original_data = cpu_req_data; - if (cpu_req_write == 4'b0000) begin + if (original_write == 4'b0000) begin NEXT_STATE = READ; end else if (mem_req_ready) begin NEXT_STATE = WRITE; @@ -253,7 +260,7 @@ always @(*) begin data_in = mem_resp_data; write_en_data = 1'b0; - mem_req_addr = cpu_req_addr[29:2] + 1; + mem_req_addr = original_addr[29:2] + 1; mem_req_valid = 1'b1; NEXT_STATE = MISS1; end @@ -268,7 +275,7 @@ always @(*) begin data_in = mem_resp_data; write_en_data = 1'b0; - mem_req_addr = cpu_req_addr[29:2] + 2; + mem_req_addr = original_addr[29:2] + 2; mem_req_valid = 1'b1; NEXT_STATE = MISS2; end @@ -283,7 +290,7 @@ always @(*) begin data_in = mem_resp_data; write_en_data = 1'b0; - mem_req_addr = cpu_req_addr[29:2] + 3; + mem_req_addr = original_addr[29:2] + 3; mem_req_valid = 1'b1; NEXT_STATE = MISS3; end From fab40f1329d1a25342493b8b81dfdac4ac6c8393 Mon Sep 17 00:00:00 2001 From: Class Account Date: Mon, 14 Dec 2020 16:04:22 -0800 Subject: [PATCH 4/5] new cache done --- src/Cache.v | 3 +-- tests/bmark/cachetest.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Cache.v b/src/Cache.v index ce2df83..d0610e3 100755 --- a/src/Cache.v +++ b/src/Cache.v @@ -242,7 +242,7 @@ always @(*) begin cpu_resp_valid = 1'b1; data_addr = index * 4 + offset[3:2]; NEXT_STATE = IDLE; - end else begin + end else if (mem_req_ready) begin write_en_tag_valid = 1'b0; tag_valid_addr = index; mem_req_valid = 1'b1; @@ -255,7 +255,6 @@ always @(*) begin begin if (mem_resp_valid) begin - data_addr = index * 4; data_in = mem_resp_data; write_en_data = 1'b0; diff --git a/tests/bmark/cachetest.c b/tests/bmark/cachetest.c index 86d8d92..55a3714 100755 --- a/tests/bmark/cachetest.c +++ b/tests/bmark/cachetest.c @@ -7,7 +7,7 @@ asm volatile ("csrw 0x51e,%[v]" :: [v]"r"(csr_val)); \ } -//#define SHORT +// #define SHORT #ifdef SHORT #define PRBS 10 #define CONST 1011556 From d195f77c69745b00dd71c93844ee08cd2b1e44a3 Mon Sep 17 00:00:00 2001 From: Class Account Date: Mon, 14 Dec 2020 16:10:45 -0800 Subject: [PATCH 5/5] all done --- par.yml | 78 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 23 deletions(-) diff --git a/par.yml b/par.yml index c677d63..518f246 100755 --- a/par.yml +++ b/par.yml @@ -3,9 +3,9 @@ # Source: hammer/src/hammer-vlsi/defaults.yml # - Valid options: # - "r0" (standard orientation) -# - "r90" (rotated 90 degrees clockwise) +# - "r90" (rotated 90 degrees clockwise) # NOT VALID # - "r180" (rotated 180 degrees) -# - "r270" (rotated 270 degrees clockwise; equivalent to -90 degrees counterclockwise) +# - "r270" (rotated 270 degrees clockwise; equivalent to -90 degrees counterclockwise) # NOT VALID # - "mx" (mirrored about the x-axis) # - "mx90" (mirrored about the x-axis, then rotated 90 degrees clockwise) # - "my" (mirrored about the y-axis) @@ -19,6 +19,38 @@ # height (float) - height in um # - Required for all types, but can be auto-filled for hierarchical and hardmacro if left blank + # #SRAM1RW64x32 + # - path: "riscv_top/mem/icache/Cache_Tag" + # type: hardmacro + # x: 95 + # y: 30 + # orientation: "my" + # master: "SRAM1RW64x32" + + # #SRAM1RW64x32 + # - path: "riscv_top/mem/dcache/Cache_Tag" + # type: hardmacro + # x: 250 + # y: 30 + # orientation: "r0" + # master: "SRAM1RW64x32" + + # #SRAM1RW256x128 + # - path: "riscv_top/mem/icache/Cache_Data" + # type: hardmacro + # x: 50 + # y: 120 + # orientation: "my" + # master: "SRAM1RW256x128" + + # #SRAM1RW256x128 + # - path: "riscv_top/mem/dcache/Cache_Data" + # type: hardmacro + # x: 250 + # y: 120 + # orientation: "r0" + # master: "SRAM1RW256x128" + vlsi.inputs.placement_constraints: - path: "riscv_top" type: toplevel @@ -44,37 +76,37 @@ vlsi.inputs.placement_constraints: # You can play around with different options of # orientations and locations to achieve good QoR - #SRAM1RW64x32 - - path: "riscv_top/mem/icache/Cache_Tag" + #SRAM2RW16x32 - ICACHE TAG - A + - path: "riscv_top/mem/icache/tag_valid_sram" type: hardmacro - x: 95 - y: 30 + x: 95.04 + y: 14.04 #30.24 orientation: "my" - master: "SRAM1RW64x32" + master: "SRAM2RW16x32" - #SRAM1RW64x32 - - path: "riscv_top/mem/dcache/Cache_Tag" + #SRAM2RW16x32 - DCACHE TAG - B + - path: "riscv_top/mem/dcache/tag_valid_sram" type: hardmacro - x: 250 - y: 30 + x: 264.6 + y: 9.72 orientation: "r0" - master: "SRAM1RW64x32" + master: "SRAM2RW16x32" - #SRAM1RW256x128 - - path: "riscv_top/mem/icache/Cache_Data" + #SRAM1RW64x128 - ICACHE DATA - C + - path: "riscv_top/mem/icache/data_sram" type: hardmacro - x: 50 - y: 120 + x: 19.44 + y: 139.32 #119.88 orientation: "my" - master: "SRAM1RW256x128" + master: "SRAM1RW64x128" - #SRAM1RW256x128 - - path: "riscv_top/mem/dcache/Cache_Data" + #SRAM1RW64x128 - DCACHE DATA - D + - path: "riscv_top/mem/dcache/data_sram" type: hardmacro - x: 250 - y: 120 + x: 284.04 + y: 140.4 #129.6 orientation: "r0" - master: "SRAM1RW256x128" + master: "SRAM1RW64x128" - path: "riscv_top/place_obs_bottom" type: obstruction @@ -126,4 +158,4 @@ par.innovus.use_cco: true # All the placement constraints specified above will be ignored. # This might lead to poor QoR and more DRVs. -#par.innovus.floorplan_mode: auto +#par.innovus.floorplan_mode: auto \ No newline at end of file