diff --git a/4mem/d_cache_daxi.sv b/4mem/d_cache_daxi.sv index f190ef8..2d597c8 100644 --- a/4mem/d_cache_daxi.sv +++ b/4mem/d_cache_daxi.sv @@ -1,3 +1,5 @@ + + `timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: @@ -22,7 +24,9 @@ module d_cache_daxi ( input wire clk, rst, //tlb - input wire no_cache, + input wire data_en_E, + // input wire no_cache, + input wire cfg_writting, //datapath input wire data_en, input wire [31:0] data_addr, @@ -142,7 +146,8 @@ module d_cache_daxi ( wire write_finish; //写事务完毕 //FSM reg [1:0] state; - parameter IDLE = 2'b00, HitJudge = 2'b01, MissHandle=2'b11, NoCache=2'b10; + parameter IDLE = 2'b00, HitJudge = 2'b01, MissHandle=2'b11; + parameter WaitCfg = 2'b10; always @(posedge clk) begin if(rst) begin @@ -150,13 +155,20 @@ module d_cache_daxi ( end else begin case(state) - IDLE : state <= (mem_read_enE | mem_write_enE) & ~stallM ? HitJudge : IDLE; - HitJudge : state <= data_en & no_cache ? NoCache : - data_en & miss ? MissHandle : + IDLE : state <= (mem_read_enE | mem_write_enE) & ~stallM & data_en_E ? HitJudge : IDLE; + HitJudge : state <= data_en & miss &~cfg_writting ? MissHandle : mem_read_enE | mem_write_enE ? HitJudge : + cfg_writting & miss? WaitCfg : IDLE; - MissHandle : state <= ~read_req & ~write_req ? IDLE : state; - NoCache : state <= read & read_finish | write & write_finish ? IDLE : NoCache; + MissHandle : state <= ~read_req & ~write_req & ~cfg_writting ? IDLE : state; + WaitCfg : state <= cfg_writting ? WaitCfg : MissHandle; + // IDLE : state <= (mem_read_enE | mem_write_enE) & ~stallM & data_en_E ? HitJudge : IDLE; + // HitJudge : state <= data_en & miss ? MissHandle : + // mem_read_enE | mem_write_enE ? HitJudge : + // IDLE; + // MissHandle : state <= ~read_req & ~write_req & ~cfg_writting ? IDLE : state; + //MissHandle : state <= read_finish | write_finish ? IDLE : state; + // NoCache : state <= read & read_finish | write & write_finish ? IDLE : NoCache; endcase end end @@ -172,19 +184,17 @@ module d_cache_daxi ( collisionM <= rst ? 0 : collisionE; end - assign stall = ~(state==IDLE || state==HitJudge && hit && ~no_cache); - assign data_rdata = hit & ~no_cache & ~collisionM ? block_sel_way[sel]: + assign stall = ~(state==IDLE || state==HitJudge && hit); + assign data_rdata = hit & ~collisionM ? block_sel_way[sel]: collisionM ? data_wdata_r: saved_rdata; //AXI always @(posedge clk) begin read_req <= (rst) ? 1'b0 : - ~no_cache && data_en && (state == HitJudge) && miss && ~read_req ? 1'b1 : - read & no_cache & (state == HitJudge) & ~read_req ? 1'b1 : + data_en && (state == HitJudge || state==WaitCfg) && miss && ~read_req && ~cfg_writting ? 1'b1 : read_finish ? 1'b0 : read_req; write_req <= (rst) ? 1'b0 : - ~no_cache & data_en && (state == HitJudge) && miss && dirty && ~write_req ? 1'b1 : - write & no_cache & (state == HitJudge) & ~read_req ? 1'b1 : + data_en && (state == HitJudge || state==WaitCfg) && miss && dirty && ~write_req && ~cfg_writting ? 1'b1 : write_finish ? 1'b0 : write_req; end always @(posedge clk) begin @@ -201,19 +211,19 @@ module d_cache_daxi ( //读事务burst传输,计数当前传递的bank的编�? reg [OFFSET_WIDTH-3:0] cnt; always @(posedge clk) begin - cnt <= rst | no_cache | read_finish ? 0 : + cnt <= rst | read_finish ? 0 : data_back ? cnt + 1 : cnt; end //写事务burst传输,计数当前传递的bank的编�? reg [OFFSET_WIDTH-3:0] wcnt; always @(posedge clk) begin - wcnt <= rst | no_cache | write_finish ? 0 : + wcnt <= rst | write_finish ? 0 : data_go ? wcnt + 1 : wcnt; end always @(posedge clk) begin saved_rdata <= rst ? 32'b0 : - ( data_back & (cnt==offset) & ~no_cache) | (no_cache & read_finish) ? rdata : saved_rdata; + data_back & (cnt==offset) ? rdata : saved_rdata; end assign data_back = raddr_rcv & (rvalid & rready); assign data_go = waddr_rcv & (wvalid & wready); @@ -221,9 +231,9 @@ module d_cache_daxi ( assign write_finish = waddr_rcv & wdata_rcv & (bvalid & bready); //AXI signal //read - assign araddr = ~no_cache ? {tag,index,5'b0}: data_addr; //如果是可以cache的数据,就把8个字的起始地址传过去,否则只传一个字的地址 - assign arlen = ~no_cache ? BLOCK_NUM-1 : 8'd0; - assign arsize = ~no_cache ? 3'd2 : {1'b0,data_rlen}; + assign araddr = {tag,index,5'b0}; //如果是可以cache的数据,就把8个字的起始地址传过去,否则只传一个字的地址 + assign arlen = BLOCK_NUM-1; + assign arsize = 3'd2 ; assign arvalid = read_req & ~raddr_rcv; assign rready = raddr_rcv; //write @@ -233,20 +243,18 @@ module d_cache_daxi ( {TAG_WIDTH{evict_mask[0]}} & tag_way[0][TAG_WIDTH : 1]| {TAG_WIDTH{evict_mask[1]}} & tag_way[1][TAG_WIDTH : 1] ), index, {OFFSET_WIDTH{1'b0}}}; - assign awaddr = ~no_cache ? dirty_write_addr : data_addr; - assign awlen = ~no_cache ? BLOCK_NUM-1 : 8'd0; - assign awsize = ~no_cache ? 3'b10 : - data_wen==4'b1111 ? 3'b10: - data_wen==4'b1100 || data_wen==4'b0011 ? 3'b01: 3'b00; + assign awaddr = dirty_write_addr; + assign awlen = BLOCK_NUM-1; + assign awsize = 3'b10 ; assign awvalid = write_req & ~waddr_rcv; - assign wdata = ~no_cache ? block_way[evict_way][wcnt] : data_wdata; - assign wstrb = ~no_cache ? 4'b1111 : data_wen; + assign wdata = block_way[evict_way][wcnt]; + assign wstrb = 4'b1111; assign wlast = {5'd0,wcnt}==awlen; assign wvalid = waddr_rcv & ~wdata_rcv; assign bready = waddr_rcv; //LRU wire write_LRU_en; - assign write_LRU_en = ~no_cache & hit & ~stallM | ~no_cache & read_finish; + assign write_LRU_en = hit & ~stallM | read_finish; always @(posedge clk) begin if(rst) begin LRU_bit <= '{default:'0}; @@ -263,10 +271,9 @@ module d_cache_daxi ( wire write_dirty_bit_en; wire write_way_sel; wire write_dirty_bit; //dirty被修改成�?�? - assign write_dirty_bit_en = ~no_cache & ( - read & read_finish | write & hit & ~stallM | - (state==MissHandle) & read_finish - ); + assign write_dirty_bit_en = read & read_finish | write & hit & ~stallM | + (state==MissHandle) & read_finish; + assign write_way_sel = write & hit ? sel : evict_way; assign write_dirty_bit = read ? 1'b0 : 1'b1; always @(posedge clk) begin @@ -306,7 +313,7 @@ module d_cache_daxi ( for(i = 0; i < WAY_NUM; i=i+1) begin: way d_tag_ram tag_ram ( .clka(clk), - .ena(~no_cache), + .ena(1'b1), .wea(wena_tag_ram_way[i]), .addra(addra), .dina(tag_ram_dina), @@ -319,7 +326,7 @@ module d_cache_daxi ( for(j = 0; j < BLOCK_NUM; j=j+1) begin: bank d_data_bank data_bank ( .clka(clk), - .ena(~no_cache), + .ena(1'b1), .wea(wena_data_bank_way[i][j]), .addra(addra), .dina(data_bank_dina), diff --git a/4mem/mem_access.sv b/4mem/mem_access.sv index 574b4ed..12b5b91 100644 --- a/4mem/mem_access.sv +++ b/4mem/mem_access.sv @@ -22,7 +22,7 @@ module mem_access ( logic ades, adel; assign M_master_except = {M_master_except_a[7:2],adel,ades}; - assign data_sram_en = mem_en && ~(|M_master_except); + assign data_sram_en = mem_en && ~(|M_master_except); //&& mem_addr != 32'hbfaffff0; assign data_sram_addr = mem_addr; // assign data_sram_addr = (mem_addr[31:28] == 4'hB) ? {4'h1, mem_addr[27:0]} : // (mem_addr[31:28] == 4'h8) ? {4'h0, mem_addr[27:0]} : diff --git a/4mem/mmu.v b/4mem/mmu.v index 96ab17e..30198d3 100644 --- a/4mem/mmu.v +++ b/4mem/mmu.v @@ -10,6 +10,7 @@ module mmu ( output wire [31:0] inst_paddr2, output wire no_cache_d, + output wire no_cache_dE, output wire no_cache_i ); @@ -31,6 +32,8 @@ module mmu ( assign no_cache_d = (data_vaddr[31:29] == 3'b101) //kseg1 ? 1'b1 : 1'b0; + assign no_cache_dE = (data_vaddr2[31:29] == 3'b101) //kseg1 + ? 1'b1 : 1'b0; assign no_cache_i = 1'b0; diff --git a/mycpu_top.v b/mycpu_top.v index b961061..58859a0 100644 --- a/mycpu_top.v +++ b/mycpu_top.v @@ -57,6 +57,7 @@ module mycpu_top ( //d_tlb - d_cache wire no_cache_d ; //数据 + wire no_cache_dE ; wire no_cache_i ; //指令 //datapath - cache @@ -173,6 +174,7 @@ module mycpu_top ( .data_paddr(data_addr), .data_paddr2(mem_addrE), .no_cache_d(no_cache_d), + .no_cache_dE(no_cache_dE), .no_cache_i(no_cache_i) ); @@ -206,10 +208,11 @@ module mycpu_top ( .rready (i_rready) ); - d_cache_daxi u_d_cache_daxi( + d_arbitrater u_d_arbitrater( .clk(clk), .rst(rst), //TLB + .no_cache_E(no_cache_dE), .no_cache(no_cache_d), //datapath diff --git a/new/d_arbitrater.v b/new/d_arbitrater.v new file mode 100644 index 0000000..80f4459 --- /dev/null +++ b/new/d_arbitrater.v @@ -0,0 +1,210 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2022/07/26 17:20:25 +// Design Name: +// Module Name: d_arbitrater +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module d_arbitrater ( + input wire clk, rst, + //tlb + input wire no_cache_E, + input wire no_cache, + //datapath + input wire data_en, + input wire [31:0] data_addr, + output wire [31:0] data_rdata, + input wire [1:0] data_rlen, + input wire [3:0] data_wen, + input wire [31:0] data_wdata, + output wire stall, + input wire [31:0] mem_addrE, + input wire mem_read_enE, + input wire mem_write_enE, + input wire stallM, + //arbitrater + output wire [31:0] araddr, + output wire [7:0] arlen, + output wire [2:0] arsize, + output wire arvalid, + input wire arready, + + input wire [31:0] rdata, + input wire rlast, + input wire rvalid, + output wire rready, + + //write + output reg [31:0] awaddr, + output reg [7:0] awlen, + output reg [2:0] awsize, + output wire awvalid, + input wire awready, + + output reg [31:0] wdata, + output reg [3:0] wstrb, + //output reg wlast, + output wire wlast, + output wire wvalid, + input wire wready, + + input wire bvalid, + output wire bready +); + + wire [31:0] cache_araddr , cache_awaddr, cfg_araddr, cfg_awaddr; + wire [31:0] cache_rdata , cfg_rdata ; + wire [7 :0] cache_arlen , cache_awlen , cfg_arlen , cfg_awlen ; + wire [2 :0] cache_arsize , cache_awsize, cfg_arsize , cfg_awsize ; + wire cache_awvalid , cfg_awvalid , cfg_arvalid, cache_arvalid; + wire [3 :0] cache_wstrb , cfg_wstrb ; + wire cache_bready , cfg_bready , cfg_rready , cache_rready ; + wire cache_stall , cfg_stall , cache_wlast, cfg_wlast ; + wire cfg_wvalid , cache_wvalid; + wire cfg_writting; + + d_cache_daxi u_d_cache_daxi( + .clk(clk), .rst(rst), + .data_en_E(~no_cache_E), + //TLB + .cfg_writting(cfg_writting), + + //datapath + .data_en(data_en & ~no_cache), + .data_addr(data_addr), + .data_rdata(cache_rdata), + .data_rlen(data_rlen), + .data_wen(data_wen), + .data_wdata(data_wdata), + .stall(cache_stall), + .mem_addrE(mem_addrE), + .mem_read_enE(mem_read_enE), + .mem_write_enE(mem_write_enE), + .stallM(stallM), + + //arbitrater + .araddr (cache_araddr ), + .arlen (cache_arlen ), + .arsize (cache_arsize ), + .arvalid (cache_arvalid), + .arready (arready), + + .rdata (rdata ), + .rlast (rlast ), + .rvalid (rvalid), + .rready (cache_rready), + + .awaddr (cache_awaddr ), + .awlen (cache_awlen ), + .awsize (cache_awsize ), + .awvalid (cache_awvalid), + .awready (awready), + + .wdata (cache_wdata ), + .wstrb (cache_wstrb ), + .wlast (cache_wlast ), + .wvalid (cache_wvalid), + .wready (wready), + + .bvalid (bvalid), + .bready (cache_bready) + ); + + + d_confreg d_cfg( + .clk(clk), .rst(rst), + + //TLB + .no_cache(no_cache), + + //datapath + .data_enE((mem_read_enE | mem_write_enE) & no_cache_E), + .data_en(data_en & no_cache), + .data_addr(data_addr), + .data_rdata(cfg_rdata), + .data_rlen(data_rlen), + .data_wen(data_wen), + .data_wdata(data_wdata), + .stall(cfg_stall), + .mem_addrE(mem_addrE), + .mem_read_enE(mem_read_enE), + .mem_write_enE(mem_write_enE), + .stallM(stallM), + + //arbitrater + .araddr (cfg_araddr ), + .arlen (cfg_arlen ), + .arsize (cfg_arsize ), + .arvalid (cfg_arvalid), + .arready (arready), + + .rdata (rdata ), + .rlast (rlast ), + .rvalid (rvalid), + .rready (cfg_rready), + + .awaddr (cfg_awaddr ), + .awlen (awlen ), + .awsize (cfg_awsize ), + .awvalid (cfg_awvalid), + .awready (awready), + + .wdata (cfg_wdata ), + .wstrb (cfg_wstrb ), + .wlast (cfg_wlast ), + .wvalid (cfg_wvalid), + .wready (wready), + + .bvalid (bvalid), + .bready (cfg_bready), + .cfg_writting (cfg_writting) + ); + assign data_rdata = no_cache ? cfg_rdata : cache_rdata; + assign stall = cache_stall | cfg_stall; + assign araddr = no_cache ? cfg_araddr: cache_araddr; + assign arlen = no_cache ? cfg_arlen : cache_arlen ; + assign arsize = no_cache ? cfg_arsize: cache_arsize; + assign arvalid = no_cache ? cfg_arvalid:cache_arvalid; + assign rready = no_cache ? cfg_rready: cache_rready; + assign awvalid = cfg_awvalid | cache_awvalid; + // assign wdata = no_cache ? cfg_wdata : cache_wdata ; + //assign wstrb = no_cache ? cfg_wstrb : cache_wstrb ; + //assign wlast = no_cache ? cfg_wlast : cache_wlast ; + assign wlast = cfg_wlast | cache_wlast; + //assign wlast = data_en & ~no_cache ? cache_wlast : 1'b1; + assign wvalid = cfg_wvalid | cache_wvalid; + assign bready = cfg_bready | cache_bready; + + always @(posedge clk) begin + if(data_en) begin + if(no_cache) begin + awaddr <= data_addr; + awsize <= data_wen==4'b1111 ? 3'b10: + data_wen==4'b1100 || data_wen==4'b0011 ? 3'b01: 3'b00; + awlen <= 8'd0; + wdata <= data_wdata; + wstrb <= data_wen; + end + else begin + awaddr <= cache_awaddr; + awsize <= cache_awsize; + awlen <= cache_awlen; + wdata <= cache_wdata; + wstrb <= cache_wstrb; + end + end + end +endmodule diff --git a/new/d_confreg.v b/new/d_confreg.v new file mode 100644 index 0000000..649800f --- /dev/null +++ b/new/d_confreg.v @@ -0,0 +1,171 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 2022/07/26 17:39:00 +// Design Name: +// Module Name: d_confreg +// Project Name: +// Target Devices: +// Tool Versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + + +module d_confreg( + input wire clk, rst, + //tlb + input wire no_cache, + //datapath + input wire data_enE, + input wire data_en, + input wire [31:0] data_addr, + output wire [31:0] data_rdata, + input wire [1:0] data_rlen, + input wire [3:0] data_wen, + input wire [31:0] data_wdata, + output wire stall, + input wire [31:0] mem_addrE, + input wire mem_read_enE, + input wire mem_write_enE, + input wire stallM, + //arbitrater + output wire [31:0] araddr, + output wire [7:0] arlen, + output wire [2:0] arsize, + output wire arvalid, + input wire arready, + + input wire [31:0] rdata, + input wire rlast, + input wire rvalid, + output wire rready, + + //write + output wire [31:0] awaddr, + input wire [7:0] awlen, + output wire [2:0] awsize, + output wire awvalid, + input wire awready, + + output wire [31:0] wdata, + output wire [3:0] wstrb, + output wire wlast, + output wire wvalid, + input wire wready, + + input wire bvalid, + output wire bready, + output wire cfg_writting + ); + wire read, write; //表示此条访存指令是写还是读 + assign read = data_en & ~(|data_wen); //load + assign write = data_en & |data_wen; //store + + reg read_req; //一次读事务 + reg write_req; //一次写事务 + reg raddr_rcv; //读事务地址握手成功 + reg waddr_rcv; //写事务地址握手成功 + reg wdata_rcv; //写数据握手成功 + wire data_back; //读事务一次数据握手成功 + wire data_go; //写事务一次数据握手成功 + wire read_finish; //读事务完毕 + wire write_finish; //写事务完毕 + reg [31:0] saved_rdata; + wire collisionE; + reg collisionM; + reg [31:0] data_wdata_r; + + reg [2:0] wcnt; + //reg [7:0] awlen_test; + wire data_go; + assign data_go = waddr_rcv & (wvalid & wready); + assign cfg_writting = write_req; + + reg [1:0] state; + parameter IDLE = 2'b00, Judge = 2'b01 , READ = 2'b10, WRITE = 2'b11; + always @(posedge clk) begin + if(rst) begin + state <= IDLE; + end + else begin + case(state) + IDLE : state <= data_enE & ~stallM ? Judge : IDLE; + Judge: state <= data_en & read ? READ : WRITE; + READ : state <= ~read_req ? IDLE : state; + WRITE: state <= ~write_req ? IDLE : state; + endcase + end + end + always @(posedge clk) begin + read_req <= (rst) ? 1'b0 : + (state==Judge) & data_en & read & ~read_req & ~collisionE? 1'b1 : + read_finish ? 1'b0 : read_req; + + write_req <= (rst) ? 1'b0 : + (state==Judge) & data_en && write? 1'b1 : + write_finish ? 1'b0 : write_req; + end + + always @(posedge clk) begin + raddr_rcv <= rst ? 1'b0 : + arvalid&&arready ? 1'b1 : + read_finish ? 1'b0 : raddr_rcv; + waddr_rcv <= rst ? 1'b0 : + awvalid&&awready ? 1'b1 : + write_finish ? 1'b0 : waddr_rcv; + wdata_rcv <= rst ? 1'b0 : + wvalid&&wready&&wlast ? 1'b1 : + write_finish ? 1'b0 : wdata_rcv; + end + + assign arvalid = read_req & ~raddr_rcv; + assign awvalid = write_req & ~waddr_rcv; + + + assign collisionE = mem_read_enE & write & (mem_addrE == data_addr); + always@(posedge clk) begin + data_wdata_r <= rst ? 0 : data_wdata; + collisionM <= rst ? 0 : collisionE; + end + + always @(posedge clk) begin + saved_rdata <= no_cache & read_finish ? rdata : saved_rdata; + end + + assign read_finish = raddr_rcv & (rvalid & rready & rlast); + assign write_finish = waddr_rcv & wdata_rcv & (bvalid & bready); + assign stall = ~(state==IDLE || state==WRITE&&~data_enE); + + assign wvalid = waddr_rcv & ~wdata_rcv; + assign bready = waddr_rcv; + + assign data_rdata = collisionM ? data_wdata_r : saved_rdata; + + assign araddr = data_addr; + assign rready = raddr_rcv; + + assign wlast = write_req & ~write_finish; + //assign awlen = 8'd0; + assign arlen = 8'd0; + assign arsize = {1'b0,data_rlen}; + + + assign awaddr = data_addr; + assign wdata = data_wdata; + assign wstrb = data_wen; + assign awsize = data_wen==4'b1111 ? 3'b10: + data_wen==4'b1100 || data_wen==4'b0011 ? 3'b01: 3'b00; + always @(posedge clk) begin + wcnt <= rst | no_cache | write_finish ? 0: + data_go ? wcnt + 1 : wcnt; + end +endmodule