blob: 93da997d15ea1744c2d47a76dff240a17304b5b7 [file] [log] [blame]
// SPDX-FileCopyrightText: 2022 RIOSLab
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
`include "params.vh"
module l1dcache
#(
// parameter XLEN = 64,
// parameter VIRTUAL_ADDR_LEN = 32,
parameter WB_DATA_LEN = 32
)
(
`ifdef USE_POWER_PINS
inout vdd, // User area 1 1.8V supply
inout vss, // User area 1 digital ground
`endif
input clk,
input rstn,
//req
input req_valid_i,
output req_ready_o,
input opcode,//0 load ,1 store
input [VIRTUAL_ADDR_LEN - 1 : 0] req_addr_i,
input [2:0] type_i,
input [XLEN -1:0] st_data_i,
input [LSU_LSQ_SIZE_WIDTH - 1 : 0] rob_index_i,
//resp
input resp_ready_i,
output resp_valid_o,
output [XLEN -1:0] ld_data_o,
output [LSU_LSQ_SIZE_WIDTH - 1 : 0] rob_index_o,
//sram
output tag_chip_en,
output tag_write_en,
output [3:0] write_tag_mask,
output [1:0] tag_index,
output [31:0] tag_data_in,
input [31:0] tag_out,
output data_chip_en_1,
output data_write_en_1,
output [3:0] write_data_mask_1,
output [1:0] data_index_1,
output [31:0] data_in_1,
input [31:0] data_out_1,
output data_chip_en_2,
output data_write_en_2,
output [3:0] write_data_mask_2,
output [1:0] data_index_2,
output [31:0] data_in_2,
input [31:0] data_out_2,
//memory
output wb_cyc_o,
output wb_stb_o,
output wb_we_o,
output [VIRTUAL_ADDR_LEN - 1 : 0] wb_adr_o,
output [WB_DATA_LEN-1:0] wb_dat_o,
output [WB_DATA_LEN/8-1:0] wb_sel_o,
output [9:0] wb_bl_o,
output wb_bry_o,
input wb_ack_i,
input [WB_DATA_LEN -1:0] wb_dat_i
);
reg input_stall = '0;
wire req_hsk;
wire req_hsk_q;
wire s1_ld_tag_is_hit;
wire s1_st_tag_is_hit;
wire s1_ld_tag_is_miss;
wire s1_st_tag_is_miss;
wire refill_hsk;
reg mshr_is_full = '0;
reg [VIRTUAL_ADDR_LEN - 1 : 0] mshr_addr = '0;
reg [2:0] mshr_type;
reg [XLEN -1:0] mshr_data;
reg mshr_opcode;
reg [LSU_LSQ_SIZE_WIDTH - 1 : 0] mshr_rob_index;
wire s1_opcode_nxt;
wire [31:0] s1_addr_nxt;
wire [63:0] s1_data_nxt;
wire [2:0] s1_type_nxt;
wire s1_valid_nxt;
wire [LSU_LSQ_SIZE_WIDTH - 1:0] s1_rob_index_nxt;
wire s1_opcode;
wire [31:0] s1_addr;
wire [63:0] s1_data;
wire [2:0] s1_type;
wire s1_valid;
wire [LSU_LSQ_SIZE_WIDTH - 1:0] s1_rob_index;
wire s2_opcode_nxt;
wire [31:0] s2_addr_nxt;
wire [63:0] s2_data_nxt;
wire [2:0] s2_type_nxt;
wire [LSU_LSQ_SIZE_WIDTH - 1:0] s2_rob_index_nxt;
wire s2_valid_nxt;
wire s2_opcode;
wire [31:0] s2_addr;
wire [63:0] s2_data;
wire [2:0] s2_type;
wire s2_valid;
wire [LSU_LSQ_SIZE_WIDTH - 1:0] s2_rob_index;
wire cache_mem_is_write;
wire cache_mem_is_write_q;
wire [63:0] wb_dat;
wire [31:0] wb_tag;
wire [63:0] st_dat;
wire [31:0] tag_out;
wire [63:0] st_dat_mask;
wire [63:0] wb_ack_i_mask;
wire [7:0] index;
wire [31:0] tag_data_in;
wire [63:0] data_in;
wire [63:0] write_data_in;
wire [63:0] data_out;
wire [7:0] write_data_mask;
wire [7:0] write_data_mask_in;
wire [63:0] ld_data_refill;
wire [63:0] ld_data_cache;
wire refill_hsk_q;
wire req_hsk_mshr_is_full;
wire req_hsk_mshr_is_full_q;
wire s1_st_tag_is_hit_q;
wire s1_st_tag_is_miss_q;
wire s1_ld_tag_is_hit_q;
wire s1_ld_tag_is_miss_q;
wire s1_opcode_nxt_q;
wire [31:0] s1_addr_nxt_q;
wire [63:0] s1_data_nxt_q;
wire [2:0] s1_type_nxt_q;
wire s1_valid_nxt_q;
wire [LSU_LSQ_SIZE_WIDTH - 1:0] s1_rob_index_nxt_q;
wire s2_opcode_nxt_q;
wire [31:0] s2_addr_nxt_q;
wire [63:0] s2_data_nxt_q;
wire [2:0] s2_type_nxt_q;
wire s2_valid_nxt_q;
wire [LSU_LSQ_SIZE_WIDTH - 1:0] s2_rob_index_nxt_q;
wire req_hsk_q_q;
wire data_chip_en;
wire data_write_en;
wire s1_stall;
wire s2_stall;
wire s1_ena;
wire s2_ena;
wire [31:0] mshr_tag_out;
wire [63:0] mshr_data_out;
wire [31:0] mshr_tag_out_q;
wire [63:0] mshr_data_out_q;
wire burst;
wire [31:0] refill_buffer;
wire [31:0] refill_buffer_q;
wire [63:0] refill_data;
wire burst_q;
reg opcode_save;
reg [VIRTUAL_ADDR_LEN - 1 : 0] addr_save;
reg [2:0] type_save;
reg [XLEN -1:0] data_save;
reg [LSU_LSQ_SIZE_WIDTH - 1 : 0] rob_index_save;
wire [31:0] tag_dout1;
wire [31:0] data_dout1;
wire [31:0] data_dout2;
wire replay;
wire replay_q;
wire replay_q_q;
reg [63:0] data_out_save;
reg start;
reg [31:0] tag_out_save;
wire [31:0] tag_out_use;
wire tag_chip_en_q;
wire tag_write_en_q;
wire s1_stall_q;
wire data_chip_en_q;
wire data_write_en_q;
wire mshr_is_full_q;
wire [63:0] st_hit_dat_mask;
wire [63:0] st_hit_dat_mask_q;
wire [63:0] st_hit_i_mask;
wire [63:0] st_hit_i_mask_q;
wire [63:0] st_hit_dat;
wire [63:0] st_hit_dat_q;
wire s1_st_tag_is_hit_q_q;
wire [31:0] s2_addr_q;
wire [31:0] s1_addr_q;
wire [63:0] data_in_Q;
wire [63:0] data_write_en_Q;
wire req_hsk_q_q_q;
wire refill_hsk_q_q;
/////////////////////////////////////////
//clean sram
reg [7:0] counter = 8'b00000000;
reg reset = '1;
always @(posedge clk) begin
if(rstn) begin
reset <= '1;
if(counter != 8'b11111111) begin
counter <= counter +1;
end else if(counter == 8'b11111111) begin
counter <= 8'b00000000;
end
end else begin
reset <= '0;
end
end
always @(posedge clk) begin
if(~rstn) begin
start <= 1'b1;
end
if(rstn) begin
start <= 1'b0;
end
end
assign tag_index = index[1:0];
assign data_index_1 = index[1:0];
assign data_index_2 = index[1:0];
assign data_chip_en_1 = data_chip_en;
assign data_chip_en_2 = data_chip_en;
assign data_write_en_1 = data_write_en;
assign data_write_en_2 = data_write_en;
assign write_data_mask_1 = write_data_mask[3:0];
assign write_data_mask_2 = write_data_mask[7:4];
assign data_in_1 = data_in[31:0];
assign data_in_2 = data_in[63:32];
assign data_out = {data_out_2,data_out_1};
wire [63:0] data_in_q;
wire [7:0] write_data_mask_q;
wire [7:0] index_q;
std_dffr #(.WIDTH(64)) DATA_IN (.clk(clk),.rstn(rstn),.d(data_in),.q(data_in_q));
std_dffr #(.WIDTH(8)) DATA_MASK (.clk(clk),.rstn(rstn),.d(write_data_mask),.q(write_data_mask_q));
std_dffr #(.WIDTH(8)) INDEX (.clk(clk),.rstn(rstn),.d(index),.q(index_q));
assign tag_chip_en = ~(req_hsk | (s2_valid & s2_opcode) | refill_hsk | reset | (refill_hsk_q & input_stall));
assign data_chip_en = ~(req_hsk | (s2_valid & s2_opcode) | refill_hsk | reset | (refill_hsk_q & input_stall));
assign index = reset ? counter :
refill_hsk ? mshr_addr[10:3] :
(refill_hsk_q & input_stall) ? addr_save[10:3] :
req_hsk ? req_addr_i[10:3] :
(s2_valid & s2_opcode) ? s2_addr[10:3]:
8'b0;
assign data_write_en = ~(reset | (s2_valid & s2_opcode) | refill_hsk);
assign tag_write_en = ~(reset | (s2_valid & s2_opcode) | refill_hsk);
assign write_data_mask_in =
(s2_opcode == 1 && s2_type == 3'b000) ? (8'b00000001 << s2_addr[2:0]):
(s2_opcode == 1 && s2_type == 3'b001) ? (8'b00000011 << s2_addr[2:0]):
(s2_opcode == 1 && s2_type == 3'b010) ? (8'b00001111 << s2_addr[2:0]):
(s2_opcode == 1 && s2_type == 3'b011) ? (8'b11111111 << s2_addr[2:0]):
8'b0;
assign write_data_in =
(s2_opcode == 1 && s2_type == 3'b000) ? (s2_data << 8*s2_addr[2:0]):
(s2_opcode == 1 && s2_type == 3'b001) ? (s2_data << 8*s2_addr[2:0]):
(s2_opcode == 1 && s2_type == 3'b010) ? (s2_data << 8*s2_addr[2:0]):
(s2_opcode == 1 && s2_type == 3'b011) ? (s2_data << 8*s2_addr[2:0]):
64'b0;
assign write_data_mask = reset ? 8'b11111111 :
refill_hsk ? 8'b11111111 :
(s2_valid & s2_opcode) ? write_data_mask_in :
8'b0;
assign write_tag_mask = reset ? 4'b1111 :
refill_hsk ? 4'b1111 :
(s2_valid & s2_opcode) ? 4'b1000:
4'b0;
assign data_in = reset ? 64'hFFFFFFFFFFFFFFFF :
refill_hsk ? wb_dat :
(s2_valid & s2_opcode) ? write_data_in :
64'b0;
assign tag_data_in = reset ? 32'hFFFFFFFF :// F
refill_hsk ? wb_tag :
(s2_valid & s2_opcode) ? {1'b1,31'b0}:
32'b0;
assign wb_bl_o = wb_stb_o ? 10'b0000000001 : 10'b0000000000;
assign wb_bry_o = wb_stb_o;
//////////////////////////////////////
//replay tag miss req when mshr is full
always @(posedge clk) begin
if (req_hsk) begin
opcode_save <= opcode;
addr_save <= req_addr_i;
type_save <= type_i;
data_save <= st_data_i;
rob_index_save <= rob_index_i;
end
end
//////////////////////////////////////
// req_ready_o and resp_valid_o and stall
assign s2_stall = refill_hsk;
assign s1_stall = refill_hsk;
always @(posedge clk) begin
if(rstn) begin
input_stall <= '0;
end else begin
if(mshr_is_full & (s1_ld_tag_is_miss | s1_st_tag_is_miss)) begin
input_stall <= '1;
end
if(refill_hsk_q & input_stall) begin
input_stall <= '0;
end
end
end
std_dffr #(.WIDTH(1)) REFILL_HSK (.clk(clk),.rstn(rstn),.d(refill_hsk),.q(refill_hsk_q));
std_dffr #(.WIDTH(1)) REFILL_HSK_1 (.clk(clk),.rstn(rstn),.d(refill_hsk_q),.q(refill_hsk_q_q));
assign req_ready_o = rstn ? 1'b1:
refill_hsk ? 1'b0 :
req_hsk_mshr_is_full_q ? 1'b0 :
input_stall ? 1'b0:
(req_hsk_q_q & (req_hsk_q | s1_st_tag_is_hit_q)) ? 1'b0:
(replay_q_q & req_hsk_q) ? 1'b0:
(replay_q_q & s1_st_tag_is_hit_q) ? 1'b0:
(s2_valid & opcode) ? 1'b0:
(req_hsk_q_q_q & req_hsk_q & refill_hsk_q_q) ? 1'b0:
1'b1;
std_dffr #(.WIDTH(1)) REQ_HSK_1 (.clk(clk),.rstn(rstn),.d(req_hsk),.q(req_hsk_q));
std_dffr #(.WIDTH(1)) REQ_HSK_2 (.clk(clk),.rstn(rstn),.d(req_hsk_q),.q(req_hsk_q_q));
std_dffr #(.WIDTH(1)) REQ_HSK_3 (.clk(clk),.rstn(rstn),.d(req_hsk_q_q),.q(req_hsk_q_q_q));
assign req_hsk_mshr_is_full = mshr_is_full & req_hsk;
std_dffr #(.WIDTH(1)) REQ_HSK_MSHR_IS_FULL (.clk(clk),.rstn(rstn),.d(req_hsk_mshr_is_full),.q(req_hsk_mshr_is_full_q));
assign resp_valid_o = refill_hsk & ~mshr_opcode ? 1'b1 :
(s2_valid & ~s2_opcode)? 1'b1 :
1'b0;
assign replay = refill_hsk_q & input_stall ? 1'b1 : 1'b0;
std_dffr #(.WIDTH(1)) REPLAY_1 (.clk(clk),.rstn(rstn),.d(replay),.q(replay_q));
std_dffr #(.WIDTH(1)) REPLAY_2 (.clk(clk),.rstn(rstn),.d(replay_q),.q(replay_q_q));
assign refill_hsk = (wb_ack_i & burst_q & resp_ready_i & ~cache_mem_is_write_q);
// 在verilator中若ack下降和clk的上升沿是同时的,则在clk高电平时会认为wb_ack_i还是高(因为在eval()时尚未ack降低)
//所以目前使ack下降先于clk上升沿,避免这一问题
//////////////////////////////////////
// mshr and mlfb
reg mshr_just_full = '0;
always @(posedge clk) begin
if(rstn) begin
mshr_is_full <= '0;
end
if((s1_st_tag_is_miss | s1_ld_tag_is_miss) & ~mshr_is_full) begin
mshr_is_full <= '1;
mshr_addr <= s1_addr;
mshr_type <= s1_type;
mshr_data <= s1_data;
mshr_opcode <= s1_opcode;
mshr_rob_index <= s1_rob_index;
mshr_just_full <='1;
end else begin
mshr_just_full <='0;
end
if(refill_hsk) begin
mshr_is_full <= '0;
end
end
assign mshr_tag_out = ((s1_st_tag_is_miss_q | s1_ld_tag_is_miss_q) & ~mshr_is_full_q & s1_st_tag_is_hit_q_q & (s2_addr_q[10:3] == s1_addr_q[10:3])) ? {1'b1,tag_out_save[30:0]} :
((s1_st_tag_is_miss_q | s1_ld_tag_is_miss_q) & ~mshr_is_full_q) ? tag_out_save :
mshr_tag_out_q;
assign data_write_en_Q = {{8{write_data_mask_q[7]}},{8{write_data_mask_q[6]}},{8{write_data_mask_q[5]}},{8{write_data_mask_q[4]}},{8{write_data_mask_q[3]}},{8{write_data_mask_q[2]}},{8{write_data_mask_q[1]}},{8{write_data_mask_q[0]}}};
assign data_in_Q = (data_write_en_Q & data_in_q) | (~data_write_en_Q & data_out_save);
assign mshr_data_out = ((s1_st_tag_is_miss_q | s1_ld_tag_is_miss_q)& ~mshr_is_full_q & s1_st_tag_is_hit_q_q & (s2_addr_q[10:3] == s1_addr_q[10:3])) ? data_in_Q :
((s1_st_tag_is_miss_q | s1_ld_tag_is_miss_q) & ~mshr_is_full_q) ? data_out_save :
mshr_data_out_q;
std_dffr #(.WIDTH(32)) MSHR_TAG_OUT (.clk(clk),.rstn(rstn),.d(mshr_tag_out),.q(mshr_tag_out_q));
std_dffr #(.WIDTH(64)) MSHR_DATA_OUT (.clk(clk),.rstn(rstn),.d(mshr_data_out),.q(mshr_data_out_q));
std_dffr #(.WIDTH(1)) MSHR_IS_FULL (.clk(clk),.rstn(rstn),.d(mshr_is_full),.q(mshr_is_full_q));
assign refill_data = {wb_dat_i,refill_buffer};
assign refill_buffer = wb_ack_i & burst ? wb_dat_i :
refill_buffer_q;
std_dffr #(.WIDTH(32)) REFILL_BUFFER (.clk(clk),.rstn(rstn),.d(refill_buffer),.q(refill_buffer_q));
assign burst = (wb_ack_i & ~burst_q) ? 1'b1:
(wb_ack_i & burst_q) ? 1'b0:
burst_q;
std_dffr #(.WIDTH(1)) BURST (.clk(clk),.rstn(rstn),.d(burst),.q(burst_q));
assign cache_mem_is_write = (wb_ack_i & cache_mem_is_write_q & burst_q) ? 1'b0 :
(s1_st_tag_is_miss_q | s1_ld_tag_is_miss_q) & (mshr_tag_out[30]==1) ? 1'b0 :
(s1_st_tag_is_miss_q | s1_ld_tag_is_miss_q) & mshr_is_full & (mshr_tag_out[31]==1) & mshr_just_full ? 1'b1 :
cache_mem_is_write_q;
std_dffr #(.WIDTH(1)) CACHE_MEM_IS_WRITE (.clk(clk),.rstn(rstn),.d(cache_mem_is_write),.q(cache_mem_is_write_q));
assign wb_stb_o = wb_ack_i ? 1'b0:
wb_cyc_o;
assign wb_cyc_o =
refill_hsk ? 1'b0:
mshr_is_full ? 1'b1 :
1'b0;
assign wb_we_o = cache_mem_is_write;
assign wb_adr_o = cache_mem_is_write & ~burst ? {mshr_tag_out[20:0],mshr_addr[10:3],3'b000}:
cache_mem_is_write & burst ? {mshr_tag_out[20:0],mshr_addr[10:3],3'b100}:
~cache_mem_is_write & ~burst ? {mshr_addr[31:3],3'b000}:
~cache_mem_is_write & burst ? {mshr_addr[31:3],3'b100}:
32'b0;
assign wb_dat_o = cache_mem_is_write & ~burst ? mshr_data_out[31:0]:
cache_mem_is_write & burst ? mshr_data_out[63:32]:
32'b0;
assign wb_sel_o = 4'b1111;
always @(posedge clk) begin
if(~tag_chip_en_q & tag_write_en_q & refill_hsk & (index_q == index)) begin
tag_out_save <= tag_data_in;
end
if(~tag_chip_en_q & tag_write_en_q & ~(refill_hsk & (index_q == index))) begin
tag_out_save <= tag_out;
end
if(~tag_chip_en_q & tag_write_en_q & refill_hsk & (index_q == index)) begin
data_out_save <= data_in;
end
if(~data_chip_en_q & data_write_en_q & s1_ld_tag_is_hit & s1_st_tag_is_hit_q & (s2_addr_nxt[31:3] == s2_addr_nxt_q[31:3])) begin
data_out_save <= st_hit_dat;
end
if(~data_chip_en_q & data_write_en_q & ~(s1_ld_tag_is_hit & s1_st_tag_is_hit_q & (s2_addr_nxt[31:3] == s2_addr_nxt_q[31:3])) & ~(refill_hsk & (index_q == index))) begin
data_out_save <= data_out;
end
end
std_dffr #(.WIDTH(1)) TAG_CHIP_EN (.clk(clk),.rstn(rstn),.d(tag_chip_en),.q(tag_chip_en_q));
std_dffr #(.WIDTH(1)) TAG_WRITE_EN (.clk(clk),.rstn(rstn),.d(tag_write_en),.q(tag_write_en_q));
std_dffr #(.WIDTH(1)) DATA_CHIP_EN (.clk(clk),.rstn(rstn),.d(data_chip_en),.q(data_chip_en_q));
std_dffr #(.WIDTH(1)) DATA_WRITE_EN (.clk(clk),.rstn(rstn),.d(data_write_en),.q(data_write_en_q));
//s0
assign req_hsk = req_valid_i & req_ready_o & start;
assign s1_opcode_nxt = req_hsk ? opcode :
refill_hsk_q & input_stall ? opcode_save :
s1_stall ? s1_opcode_nxt_q :
1'b0;
assign s1_addr_nxt = req_hsk ? req_addr_i :
s1_stall ? s1_addr_nxt_q :
refill_hsk_q & input_stall ? addr_save :
32'b0;
assign s1_data_nxt = req_hsk ? st_data_i :
refill_hsk_q & input_stall ? data_save :
s1_stall ? s1_data_nxt_q :
64'b0;
assign s1_type_nxt = req_hsk ? type_i :
refill_hsk_q & input_stall ? type_save :
s1_stall ? s1_type_nxt_q :
3'b0;
assign s1_rob_index_nxt = req_hsk ? rob_index_i :
refill_hsk_q & input_stall ? rob_index_save :
s1_stall ? s1_rob_index_nxt_q :
1'b0;
assign s1_valid_nxt = req_hsk ? 1'b1 :
refill_hsk_q & input_stall ? 1'b1 :
s1_stall ? s1_valid_nxt_q :
1'b0;
assign s1_ena = s1_stall ? 1'b0 : 1'b1;
std_dffr #(.WIDTH(1)) S1_OPCODE_Q (.clk(clk),.rstn(rstn),.d(s1_opcode_nxt),.q(s1_opcode_nxt_q));
std_dffr #(.WIDTH(32)) S1_ADDR_Q (.clk(clk),.rstn(rstn),.d(s1_addr_nxt),.q(s1_addr_nxt_q));
std_dffr #(.WIDTH(64)) S1_DATA_Q (.clk(clk),.rstn(rstn),.d(s1_data_nxt),.q(s1_data_nxt_q));
std_dffr #(.WIDTH(3)) S1_TYPE_Q (.clk(clk),.rstn(rstn),.d(s1_type_nxt),.q(s1_type_nxt_q));
std_dffr #(.WIDTH(1)) S1_VALID_Q (.clk(clk),.rstn(rstn),.d(s1_valid_nxt),.q(s1_valid_nxt_q));
std_dffr #(.WIDTH(1)) S1_ROB_INDEX_Q (.clk(clk),.rstn(rstn),.d(s1_rob_index_nxt),.q(s1_rob_index_nxt_q));
std_dffe #(.WIDTH(1)) S1_OPCODE (.clk(clk),.en(s1_ena),.d(s1_opcode_nxt),.q(s1_opcode));
std_dffe #(.WIDTH(32)) S1_ADDR (.clk(clk),.en(s1_ena),.d(s1_addr_nxt),.q(s1_addr));
std_dffe #(.WIDTH(64)) S1_DATA (.clk(clk),.en(s1_ena),.d(s1_data_nxt),.q(s1_data));
std_dffe #(.WIDTH(3)) S1_TYPE (.clk(clk),.en(s1_ena),.d(s1_type_nxt),.q(s1_type));
std_dffe #(.WIDTH(1)) S1_VALID (.clk(clk),.en(s1_ena),.d(s1_valid_nxt),.q(s1_valid));
std_dffe #(.WIDTH(1)) S1_ROB_INDEX (.clk(clk),.en(s1_ena),.d(s1_rob_index_nxt),.q(s1_rob_index));
std_dffr #(.WIDTH(32)) S1_ADDR_Q_Q (.clk(clk),.rstn(rstn),.d(s1_addr),.q(s1_addr_q));
assign tag_out_use = s1_stall_q ? tag_out_save : tag_out;
std_dffr #(.WIDTH(1)) S1_STALL (.clk(clk),.rstn(rstn),.d(s1_stall),.q(s1_stall_q));
//s1
// assign s1_ld_tag_is_hit = s1_valid & (s1_addr[31:11] == tag_out_use[20:0]) & (s1_opcode==0) & (tag_out_use[30] == 0) & ~((tag_out_use[20:0] == mshr_addr[31:11]) & (mshr_is_full == 1));
// assign s1_st_tag_is_hit = s1_valid & (s1_addr[31:11] == tag_out_use[20:0]) & (s1_opcode==1) & (tag_out_use[30] == 0) & ~((tag_out_use[20:0] == mshr_addr[31:11]) & (mshr_is_full == 1));
assign s1_ld_tag_is_hit = s1_valid & (s1_addr[31:11] == tag_out_use[20:0]) & (s1_opcode==0) & (tag_out_use[30] == 0) & ~((s1_addr[10:3] == mshr_addr[10:3]) & (mshr_is_full == 1));
assign s1_st_tag_is_hit = s1_valid & (s1_addr[31:11] == tag_out_use[20:0]) & (s1_opcode==1) & (tag_out_use[30] == 0) & ~((s1_addr[10:3] == mshr_addr[10:3]) & (mshr_is_full == 1));
assign s1_ld_tag_is_miss = (s1_valid & ~s1_opcode) ? ~s1_ld_tag_is_hit : 1'b0;
assign s1_st_tag_is_miss = (s1_valid & s1_opcode) ? ~s1_st_tag_is_hit : 1'b0;
std_dffr #(.WIDTH(1)) S1_LD_TAG_IS_HIT (.clk(clk),.rstn(rstn),.d(s1_ld_tag_is_hit),.q(s1_ld_tag_is_hit_q));
std_dffr #(.WIDTH(1)) S1_ST_TAG_IS_HIT (.clk(clk),.rstn(rstn),.d(s1_st_tag_is_hit),.q(s1_st_tag_is_hit_q));
std_dffr #(.WIDTH(1)) S1_ST_TAG_IS_HIT_Q (.clk(clk),.rstn(rstn),.d(s1_st_tag_is_hit_q),.q(s1_st_tag_is_hit_q_q));
std_dffr #(.WIDTH(1)) S1_LD_TAG_IS_MISS (.clk(clk),.rstn(rstn),.d(s1_ld_tag_is_miss),.q(s1_ld_tag_is_miss_q));
std_dffr #(.WIDTH(1)) S1_ST_TAG_IS_MISS (.clk(clk),.rstn(rstn),.d(s1_st_tag_is_miss),.q(s1_st_tag_is_miss_q));
assign s2_opcode_nxt = (s1_ld_tag_is_hit | s1_st_tag_is_hit ) ? s1_opcode :
s2_stall ? s2_opcode_nxt_q :
1'b0;
assign s2_addr_nxt = (s1_ld_tag_is_hit | s1_st_tag_is_hit ) ? s1_addr :
s2_stall ? s2_addr_nxt_q :
32'b0;
assign s2_data_nxt = (s1_ld_tag_is_hit | s1_st_tag_is_hit ) ? s1_data :
s2_stall ? s2_data_nxt_q :
64'b0;
assign s2_type_nxt = (s1_ld_tag_is_hit | s1_st_tag_is_hit ) ? s1_type :
s2_stall ? s2_type_nxt_q :
3'b0;
assign s2_rob_index_nxt = (s1_ld_tag_is_hit | s1_st_tag_is_hit ) ? s1_rob_index :
s2_stall ? s2_rob_index_nxt_q :
1'b0;
assign s2_valid_nxt = (s1_ld_tag_is_hit | s1_st_tag_is_hit ) ? 1'b1 :
s2_stall ? s2_valid_nxt_q :
1'b0 ;
assign s2_ena = s2_stall ? 1'b0 : 1'b1;
std_dffr #(.WIDTH(1)) S2_OPCODE_Q (.clk(clk),.rstn(rstn),.d(s2_opcode_nxt),.q(s2_opcode_nxt_q));
std_dffr #(.WIDTH(32)) S2_ADDR_Q (.clk(clk),.rstn(rstn),.d(s2_addr_nxt),.q(s2_addr_nxt_q));
std_dffr #(.WIDTH(64)) S2_DATA_Q (.clk(clk),.rstn(rstn),.d(s2_data_nxt),.q(s2_data_nxt_q));
std_dffr #(.WIDTH(3)) S2_TYPE_Q (.clk(clk),.rstn(rstn),.d(s2_type_nxt),.q(s2_type_nxt_q));
std_dffr #(.WIDTH(1)) S2_VALID_Q (.clk(clk),.rstn(rstn),.d(s2_valid_nxt),.q(s2_valid_nxt_q));
std_dffr #(.WIDTH(1)) S2_ROB_INDEX_Q (.clk(clk),.rstn(rstn),.d(s2_rob_index_nxt),.q(s2_rob_index_nxt_q));
std_dffe #(.WIDTH(1)) S2_OPCODE (.clk(clk),.en(s2_ena),.d(s2_opcode_nxt),.q(s2_opcode));
std_dffe #(.WIDTH(32)) S2_ADDR (.clk(clk),.en(s2_ena),.d(s2_addr_nxt),.q(s2_addr));
std_dffe #(.WIDTH(64)) S2_DATA (.clk(clk),.en(s2_ena),.d(s2_data_nxt),.q(s2_data));
std_dffe #(.WIDTH(3)) S2_TYPE (.clk(clk),.en(s2_ena),.d(s2_type_nxt),.q(s2_type));
std_dffe #(.WIDTH(1)) S2_VALID (.clk(clk),.en(s2_ena),.d(s2_valid_nxt),.q(s2_valid));
std_dffe #(.WIDTH(1)) S2_ROB_INDEX (.clk(clk),.en(s2_ena),.d(s2_rob_index_nxt),.q(s2_rob_index));
std_dffr #(.WIDTH(32)) S2_ADDR_Q_Q (.clk(clk),.rstn(rstn),.d(s2_addr),.q(s2_addr_q));
//s2 resp
assign ld_data_cache = (s2_opcode == 0 && s2_type == 3'b000) ? {{56{data_out_save[s2_addr[2:0]*8+7]}},{data_out_save[s2_addr[2:0]*8+:8]}}:
(s2_opcode == 0 && s2_type == 3'b001) ? {{48{data_out_save[s2_addr[2:0]*8+15]}},{data_out_save[s2_addr[2:0]*8+:16]}}:
(s2_opcode == 0 && s2_type == 3'b010) ? {{32{data_out_save[s2_addr[2:0]*8+31]}},{data_out_save[s2_addr[2:0]*8+:32]}}:
(s2_opcode == 0 && s2_type == 3'b100) ? {56'b0,{data_out_save[s2_addr[2:0]*8+:8]}}:
(s2_opcode == 0 && s2_type == 3'b101) ? {48'b0,{data_out_save[s2_addr[2:0]*8+:16]}}:
(s2_opcode == 0 && s2_type == 3'b110) ? {32'b0,{data_out_save[s2_addr[2:0]*8+:32]}}:
(s2_opcode == 0 && s2_type == 3'b011) ? data_out_save:
64'b0;
assign ld_data_refill = (mshr_opcode == 0 && mshr_type == 3'b000) ? {{56{refill_data[mshr_addr[2:0]*8+7]}}, {refill_data[mshr_addr[2:0]*8+:8]}}:
(mshr_opcode == 0 && mshr_type == 3'b001) ? {{48{refill_data[mshr_addr[2:0]*8+15]}},{refill_data[mshr_addr[2:0]*8+:16]}}:
(mshr_opcode == 0 && mshr_type == 3'b010) ? {{32{refill_data[mshr_addr[2:0]*8+31]}},{refill_data[mshr_addr[2:0]*8+:32]}}:
(mshr_opcode == 0 && mshr_type == 3'b110) ? {32'b0,refill_data[mshr_addr[2:0]*8+:32]}:
(mshr_opcode == 0 && mshr_type == 3'b100) ? {56'b0,refill_data[mshr_addr[2:0]*8+:8]}:
(mshr_opcode == 0 && mshr_type == 3'b101) ? {48'b0,refill_data[mshr_addr[2:0]*8+:16]}:
(mshr_opcode == 0 && mshr_type == 3'b011) ? refill_data:
64'b0;
assign wb_dat = ~mshr_opcode ? refill_data :
mshr_opcode ? st_dat :
64'b0;
assign wb_tag = ~mshr_opcode ? {11'b0,mshr_addr[31:11]} :
mshr_opcode ? {11'b10000000000,mshr_addr[31:11]} :
32'b0;
assign st_dat_mask =(mshr_opcode == 1 && mshr_type == 3'b000) ? 64'h00000000000000FF << mshr_addr[2:0]*8 :
(mshr_opcode == 1 && mshr_type == 3'b001) ? 64'h000000000000FFFF << mshr_addr[2:0]*8 :
(mshr_opcode == 1 && mshr_type == 3'b010) ? 64'h00000000FFFFFFFF << mshr_addr[2:0]*8 :
(mshr_opcode == 1 && mshr_type == 3'b011) ? 64'hFFFFFFFFFFFFFFFF:
64'b0;
assign wb_ack_i_mask = ~st_dat_mask & refill_data;
assign st_dat = (mshr_opcode == 1 && mshr_type == 3'b000) ? ((mshr_data & 64'hff )<< mshr_addr[2:0]*8) | wb_ack_i_mask :
(mshr_opcode == 1 && mshr_type == 3'b001) ? ((mshr_data & 64'hffff) << mshr_addr[2:0]*8) | wb_ack_i_mask :
(mshr_opcode == 1 && mshr_type == 3'b010) ? ((mshr_data & 64'hffffffff) << mshr_addr[2:0]*8) | wb_ack_i_mask :
(mshr_opcode == 1 && mshr_type == 3'b011) ? (mshr_data << mshr_addr[2:0]*8) | wb_ack_i_mask :
64'b0;
assign st_hit_dat_mask =(s1_st_tag_is_hit && s1_type == 3'b000) ? 64'h00000000000000FF << s1_addr[2:0]*8 :
(s1_st_tag_is_hit && s1_type == 3'b001) ? 64'h000000000000FFFF << s1_addr[2:0]*8 :
(s1_st_tag_is_hit && s1_type == 3'b010) ? 64'h00000000FFFFFFFF << s1_addr[2:0]*8 :
(s1_st_tag_is_hit && s1_type == 3'b011) ? 64'hFFFFFFFFFFFFFFFF:
st_hit_dat_mask_q;
assign st_hit_i_mask = s1_st_tag_is_hit ? (~st_hit_dat_mask & data_out) : st_hit_i_mask_q ;
assign st_hit_dat = (s1_st_tag_is_hit && s1_type == 3'b000) ? ((s1_data & 64'hff)<< s1_addr[2:0]*8) | st_hit_i_mask :
(s1_st_tag_is_hit && s1_type == 3'b001) ? ((s1_data & 64'hffff) << s1_addr[2:0]*8) | st_hit_i_mask :
(s1_st_tag_is_hit && s1_type == 3'b010) ? ((s1_data & 64'hffffffff) << s1_addr[2:0]*8) | st_hit_i_mask :
(s1_st_tag_is_hit && s1_type == 3'b011) ? (s1_data << s1_addr[2:0]*8) | st_hit_i_mask :
st_hit_dat_q;
std_dffr #(.WIDTH(64))ST_HIT_DAT_MASK (.clk(clk),.rstn(rstn),.d(st_hit_dat_mask),.q(st_hit_dat_mask_q));
std_dffr #(.WIDTH(64))ST_HIT_I_MASK (.clk(clk),.rstn(rstn),.d(st_hit_i_mask),.q(st_hit_i_mask_q));
std_dffr #(.WIDTH(64))ST_HIT_DAT (.clk(clk),.rstn(rstn),.d(st_hit_dat),.q(st_hit_dat_q));
///resp ld
assign ld_data_o = refill_hsk ? ld_data_refill :
s2_valid ? ld_data_cache :
64'b0;
assign rob_index_o = refill_hsk ? mshr_rob_index :
s2_valid ? s2_rob_index :
1'b0;
endmodule