368 lines
23 KiB
Scala
368 lines
23 KiB
Scala
|
package lsu
|
||
|
import include._
|
||
|
import lib._
|
||
|
import snapshot._
|
||
|
|
||
|
import chisel3._
|
||
|
import chisel3.util._
|
||
|
import chisel3.iotesters.{ChiselFlatSpec, Driver, PeekPokeTester}
|
||
|
import chisel3.experimental.ChiselEnum
|
||
|
import chisel3.experimental.{withClock, withReset, withClockAndReset}
|
||
|
import chisel3.experimental.BundleLiterals._
|
||
|
import chisel3.tester._
|
||
|
import chisel3.tester.RawTester.test
|
||
|
import chisel3.util.HasBlackBoxResource
|
||
|
|
||
|
import chisel3.experimental.chiselName
|
||
|
@chiselName
|
||
|
class el2_lsu_dccm_ctl extends Module with RequireAsyncReset
|
||
|
{
|
||
|
val io = IO(new Bundle{
|
||
|
//val rst_l = IO(Input(1.W)) //implicit
|
||
|
val lsu_c2_m_clk = Input(Clock())
|
||
|
val lsu_c2_r_clk = Input(Clock())
|
||
|
val lsu_free_c2_clk = Input(Clock()) //tbd
|
||
|
val lsu_c1_r_clk = Input(Clock())
|
||
|
val lsu_store_c1_r_clk = Input(Clock())
|
||
|
// val clk = Input(Clock()) //tbd
|
||
|
|
||
|
val lsu_pkt_d = Input(new el2_lsu_pkt_t())
|
||
|
val lsu_pkt_m = Input(new el2_lsu_pkt_t())
|
||
|
val lsu_pkt_r = Input(new el2_lsu_pkt_t())
|
||
|
|
||
|
val addr_in_dccm_d = Input(UInt(1.W))
|
||
|
val addr_in_dccm_m = Input(UInt(1.W))
|
||
|
val addr_in_dccm_r = Input(UInt(1.W))
|
||
|
val addr_in_pic_d = Input(UInt(1.W))
|
||
|
val addr_in_pic_m = Input(UInt(1.W))
|
||
|
val addr_in_pic_r = Input(UInt(1.W))
|
||
|
|
||
|
val lsu_raw_fwd_lo_r = Input(UInt(1.W))
|
||
|
val lsu_raw_fwd_hi_r = Input(UInt(1.W))
|
||
|
val lsu_commit_r = Input(UInt(1.W))
|
||
|
|
||
|
// lsu address down the pipe
|
||
|
val lsu_addr_d = Input(UInt(32.W))//verify bits
|
||
|
val lsu_addr_m = Input(UInt(pt1.DCCM_BITS.W))
|
||
|
val lsu_addr_r = Input(UInt(32.W))
|
||
|
|
||
|
// lsu address down the pipe - needed to check unaligned
|
||
|
val end_addr_d = Input(UInt(pt1.DCCM_BITS.W))
|
||
|
val end_addr_m = Input(UInt(pt1.DCCM_BITS.W))
|
||
|
val end_addr_r = Input(UInt(pt1.DCCM_BITS.W))
|
||
|
|
||
|
val stbuf_reqvld_any = Input(UInt(1.W))
|
||
|
val stbuf_addr_any = Input(UInt(pt1.LSU_SB_BITS.W))
|
||
|
val stbuf_data_any = Input(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val stbuf_ecc_any = Input(UInt(pt1.DCCM_ECC_WIDTH.W))
|
||
|
val stbuf_fwddata_hi_m = Input(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val stbuf_fwddata_lo_m = Input(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val stbuf_fwdbyteen_lo_m = Input(UInt(pt1.DCCM_BYTE_WIDTH.W))
|
||
|
val stbuf_fwdbyteen_hi_m = Input(UInt(pt1.DCCM_BYTE_WIDTH.W))
|
||
|
val dccm_rdata_hi_r = Output(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val dccm_rdata_lo_r = Output(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val dccm_data_ecc_hi_r = Output(UInt(pt1.DCCM_ECC_WIDTH.W))
|
||
|
val dccm_data_ecc_lo_r = Output(UInt(pt1.DCCM_ECC_WIDTH.W))
|
||
|
val lsu_ld_data_r = Output(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val lsu_ld_data_corr_r = Output(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val lsu_double_ecc_error_r = Input(UInt(1.W))
|
||
|
val single_ecc_error_hi_r = Input(UInt(1.W))
|
||
|
val single_ecc_error_lo_r = Input(UInt(1.W))
|
||
|
val sec_data_hi_r = Input(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val sec_data_lo_r = Input(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val sec_data_hi_r_ff = Input(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val sec_data_lo_r_ff = Input(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val sec_data_ecc_hi_r_ff = Input(UInt(pt1.DCCM_ECC_WIDTH.W))
|
||
|
val sec_data_ecc_lo_r_ff = Input(UInt(pt1.DCCM_ECC_WIDTH.W))
|
||
|
val dccm_rdata_hi_m = Output(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val dccm_rdata_lo_m = Output(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val dccm_data_ecc_hi_m = Output(UInt(pt1.DCCM_ECC_WIDTH.W))
|
||
|
val dccm_data_ecc_lo_m = Output(UInt(pt1.DCCM_ECC_WIDTH.W))
|
||
|
val lsu_ld_data_m = Output(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val lsu_double_ecc_error_m = Input(UInt(1.W))
|
||
|
val sec_data_hi_m = Input(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val sec_data_lo_m = Input(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val store_data_m = Input(UInt(32.W))
|
||
|
val dma_dccm_wen = Input(UInt(1.W))
|
||
|
val dma_pic_wen = Input(UInt(1.W))
|
||
|
val dma_mem_tag_m = Input(UInt(3.W))
|
||
|
val dma_mem_addr = Input(UInt(32.W))
|
||
|
val dma_mem_wdata = Input(UInt(64.W))
|
||
|
val dma_dccm_wdata_lo = Input(UInt(32.W))
|
||
|
val dma_dccm_wdata_hi = Input(UInt(32.W))
|
||
|
val dma_dccm_wdata_ecc_hi = Input(UInt(pt1.DCCM_ECC_WIDTH.W))
|
||
|
val dma_dccm_wdata_ecc_lo = Input(UInt(pt1.DCCM_ECC_WIDTH.W))
|
||
|
val store_data_hi_r = Output(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val store_data_lo_r = Output(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val store_datafn_hi_r = Output(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val store_datafn_lo_r = Output(UInt(pt1.DCCM_DATA_WIDTH.W))
|
||
|
val store_data_r = Output(UInt(32.W))
|
||
|
val ld_single_ecc_error_r = Output(UInt(1.W))
|
||
|
val ld_single_ecc_error_r_ff = Output(UInt(1.W))
|
||
|
val picm_mask_data_m = Output(UInt(32.W))
|
||
|
val lsu_stbuf_commit_any = Output(UInt(1.W))
|
||
|
val lsu_dccm_rden_m = Output(UInt(1.W))
|
||
|
val lsu_dccm_rden_r = Output(UInt(1.W))
|
||
|
val dccm_dma_rvalid = Output(UInt(1.W))
|
||
|
val dccm_dma_ecc_error = Output(UInt(1.W))
|
||
|
val dccm_dma_rtag = Output(UInt(3.W))
|
||
|
val dccm_dma_rdata = Output(UInt(64.W))
|
||
|
val dccm_wren = Output(UInt(1.W))
|
||
|
val dccm_rden = Output(UInt(1.W))
|
||
|
val dccm_wr_addr_lo = Output(UInt(pt1.DCCM_BITS.W))
|
||
|
val dccm_wr_data_lo = Output(UInt(pt1.DCCM_FDATA_WIDTH.W))
|
||
|
val dccm_rd_addr_lo = Output(UInt(pt1.DCCM_BITS.W))
|
||
|
val dccm_rd_data_lo = Input(UInt(pt1.DCCM_FDATA_WIDTH.W))
|
||
|
val dccm_wr_addr_hi = Output(UInt(pt1.DCCM_BITS.W))
|
||
|
val dccm_wr_data_hi = Output(UInt(pt1.DCCM_FDATA_WIDTH.W))
|
||
|
val dccm_rd_addr_hi = Output(UInt(pt1.DCCM_BITS.W))
|
||
|
val dccm_rd_data_hi = Input(UInt(pt1.DCCM_FDATA_WIDTH.W))
|
||
|
val picm_wren = Output(UInt(1.W))
|
||
|
val picm_rden = Output(UInt(1.W))
|
||
|
val picm_mken = Output(UInt(1.W))
|
||
|
val picm_rdaddr = Output(UInt(32.W))
|
||
|
val picm_wraddr = Output(UInt(32.W))
|
||
|
val picm_wr_data = Output(UInt(32.W))
|
||
|
val picm_rd_data = Input(UInt(32.W))
|
||
|
val scan_mode = Input(UInt(1.W))
|
||
|
})
|
||
|
val picm_rd_data_m = Cat(io.picm_rd_data,io.picm_rd_data) //used in both if and else
|
||
|
val dccm_rdata_corr_r = Cat(io.sec_data_hi_r,io.sec_data_lo_r)
|
||
|
val dccm_rdata_corr_m = Cat(io.sec_data_hi_m,io.sec_data_lo_m)
|
||
|
val dccm_rdata_r = Cat(io.dccm_rdata_hi_r,io.dccm_rdata_lo_r)
|
||
|
val dccm_rdata_m = Cat(io.dccm_rdata_hi_m,io.dccm_rdata_lo_m)
|
||
|
val lsu_rdata_r = WireInit(UInt(64.W),0.U)
|
||
|
val lsu_rdata_m = WireInit(UInt(64.W),0.U)
|
||
|
val lsu_rdata_corr_r = WireInit(UInt(64.W),0.U)
|
||
|
val lsu_rdata_corr_m = WireInit(UInt(64.W),0.U)
|
||
|
val stbuf_fwddata_r = WireInit(UInt(64.W),0.U)
|
||
|
val stbuf_fwdbyteen_r = WireInit(UInt(64.W),0.U)
|
||
|
val picm_rd_data_r_32 = WireInit(UInt(32.W),0.U)
|
||
|
val picm_rd_data_r = WireInit(UInt(64.W),0.U)
|
||
|
val lsu_ld_data_corr_m = WireInit(UInt(64.W),0.U)
|
||
|
|
||
|
|
||
|
//Forwarding stbuf
|
||
|
if (pt.LOAD_TO_USE_PLUS1 == 1){
|
||
|
io.dccm_dma_rvalid := io.lsu_pkt_r.valid & io.lsu_pkt_r.load & io.lsu_pkt_r.dma
|
||
|
io.dccm_dma_ecc_error := io.lsu_double_ecc_error_r //from ecc
|
||
|
io.dccm_dma_rdata := lsu_rdata_corr_r
|
||
|
//Registers
|
||
|
io.dccm_rdata_hi_r := rvdffe(io.dccm_rdata_hi_m,io.lsu_dccm_rden_m.asBool,clock,io.scan_mode.asBool)
|
||
|
io.dccm_rdata_lo_r := rvdffe(io.dccm_rdata_lo_m,io.lsu_dccm_rden_m.asBool,clock,io.scan_mode.asBool)
|
||
|
io.dccm_data_ecc_hi_r := rvdffe(io.dccm_data_ecc_hi_m,io.lsu_dccm_rden_m.asBool,clock,io.scan_mode.asBool)
|
||
|
io.dccm_data_ecc_lo_r := rvdffe(io.dccm_data_ecc_lo_m,io.lsu_dccm_rden_m.asBool,clock,io.scan_mode.asBool)
|
||
|
stbuf_fwdbyteen_r := withClock(io.lsu_c2_r_clk){RegNext(Cat(io.stbuf_fwdbyteen_hi_m,io.stbuf_fwdbyteen_lo_m),0.U)}
|
||
|
stbuf_fwddata_r := withClock(io.lsu_c2_r_clk){RegNext(Cat(io.stbuf_fwddata_hi_m ,io.stbuf_fwddata_lo_m ),0.U)}
|
||
|
picm_rd_data_r_32 := withClock(io.lsu_c2_r_clk){RegNext(picm_rd_data_m(31,0),0.U)}
|
||
|
picm_rd_data_r := Cat(picm_rd_data_r_32,picm_rd_data_r_32)
|
||
|
io.dccm_dma_rtag := withClock(io.lsu_c1_r_clk){RegNext(io.dma_mem_tag_m,0.U)}
|
||
|
|
||
|
lsu_rdata_corr_r := Reverse(Cat(VecInit.tabulate(8)(i=> Reverse(Mux(stbuf_fwdbyteen_r(i).asBool,stbuf_fwddata_r((8*i)+7,8*i),Mux(io.addr_in_pic_r.asBool,picm_rd_data_r((8*i)+7,8*i),dccm_rdata_corr_r((8*i)+7,8*i)))))))
|
||
|
lsu_rdata_r := Reverse(Cat(VecInit.tabulate(8)(i=> Reverse(Mux(stbuf_fwdbyteen_r(i).asBool,stbuf_fwddata_r((8*i)+7,8*i),Mux(io.addr_in_pic_r.asBool,picm_rd_data_r((8*i)+7,8*i),dccm_rdata_r((8*i)+7,8*i)))))))
|
||
|
io.lsu_ld_data_r := lsu_rdata_r>> 8.U*io.lsu_addr_r(1,0)
|
||
|
io.lsu_ld_data_corr_r := lsu_rdata_corr_r >> 8.U*io.lsu_addr_r(1,0)
|
||
|
}
|
||
|
|
||
|
else{
|
||
|
io.dccm_dma_rvalid := io.lsu_pkt_m.valid & io.lsu_pkt_m.load & io.lsu_pkt_m.dma
|
||
|
io.dccm_dma_ecc_error := io.lsu_double_ecc_error_m //from ecc
|
||
|
io.dccm_dma_rdata := lsu_rdata_corr_m
|
||
|
io.dccm_dma_rtag := io.dma_mem_tag_m
|
||
|
io.dccm_rdata_lo_r := 0.U
|
||
|
io.dccm_rdata_hi_r := 0.U
|
||
|
io.dccm_data_ecc_hi_r := 0.U
|
||
|
io.dccm_data_ecc_lo_r := 0.U
|
||
|
io.lsu_ld_data_r := 0.U
|
||
|
//Registers
|
||
|
io.lsu_ld_data_corr_r := withClock(io.lsu_c2_r_clk){RegNext(lsu_ld_data_corr_m,0.U)}
|
||
|
lsu_rdata_corr_m := Reverse(Cat(VecInit.tabulate(8)(i=> Reverse(Mux(((Cat(io.stbuf_fwdbyteen_hi_m,io.stbuf_fwdbyteen_lo_m))(i)).asBool,(Cat(io.stbuf_fwddata_hi_m,io.stbuf_fwddata_lo_m))((8*i)+7,8*i),Mux(io.addr_in_pic_m.asBool,picm_rd_data_m((8*i)+7,8*i),dccm_rdata_corr_m((8*i)+7,8*i)))))))
|
||
|
lsu_rdata_m := Reverse(Cat(VecInit.tabulate(8)(i=> Reverse(Mux(((Cat(io.stbuf_fwdbyteen_hi_m,io.stbuf_fwdbyteen_lo_m))(i)).asBool,(Cat(io.stbuf_fwddata_hi_m,io.stbuf_fwddata_lo_m))((8*i)+7,8*i),Mux(io.addr_in_pic_m.asBool,picm_rd_data_m((8*i)+7,8*i),dccm_rdata_m((8*i)+7,8*i)))))))
|
||
|
io.lsu_ld_data_m := lsu_rdata_m >> 8.U*io.lsu_addr_m(1,0)
|
||
|
lsu_ld_data_corr_m := lsu_rdata_corr_m >> 8.U*io.lsu_addr_m(1,0)
|
||
|
}
|
||
|
|
||
|
//Ecc error kill
|
||
|
val kill_ecc_corr_lo_r = (((io.lsu_addr_d(pt1.DCCM_BITS-1,2) === io.lsu_addr_r(pt1.DCCM_BITS-1,2)).asUInt | (io.end_addr_d(pt1.DCCM_BITS-1,2) === io.lsu_addr_r(pt1.DCCM_BITS-1,2)).asUInt) & io.lsu_pkt_d.valid & io.lsu_pkt_d.store & io.lsu_pkt_d.dma & io.addr_in_dccm_d) |
|
||
|
(((io.lsu_addr_m(pt1.DCCM_BITS-1,2) === io.lsu_addr_r(pt1.DCCM_BITS-1,2)).asUInt | (io.end_addr_m(pt1.DCCM_BITS-1,2) === io.lsu_addr_r(pt1.DCCM_BITS-1,2)).asUInt) & io.lsu_pkt_m.valid & io.lsu_pkt_m.store & io.lsu_pkt_m.dma & io.addr_in_dccm_m)
|
||
|
|
||
|
val kill_ecc_corr_hi_r = (((io.lsu_addr_d(pt1.DCCM_BITS-1,2) === io.end_addr_r(pt1.DCCM_BITS-1,2)).asUInt | (io.end_addr_d(pt1.DCCM_BITS-1,2) === io.end_addr_r(pt1.DCCM_BITS-1,2)).asUInt) & io.lsu_pkt_d.valid & io.lsu_pkt_d.store & io.lsu_pkt_d.dma & io.addr_in_dccm_d) |
|
||
|
(((io.lsu_addr_m(pt1.DCCM_BITS-1,2) === io.end_addr_r(pt1.DCCM_BITS-1,2)).asUInt | (io.end_addr_m(pt1.DCCM_BITS-1,2) === io.end_addr_r(pt1.DCCM_BITS-1,2)).asUInt) & io.lsu_pkt_m.valid & io.lsu_pkt_m.store & io.lsu_pkt_m.dma & io.addr_in_dccm_m)
|
||
|
|
||
|
val ld_single_ecc_error_lo_r = io.lsu_pkt_r.load & io.single_ecc_error_lo_r & ~io.lsu_raw_fwd_lo_r
|
||
|
val ld_single_ecc_error_hi_r = io.lsu_pkt_r.load & io.single_ecc_error_hi_r & ~io.lsu_raw_fwd_hi_r
|
||
|
io.ld_single_ecc_error_r := (ld_single_ecc_error_lo_r | ld_single_ecc_error_hi_r) & ~io.lsu_double_ecc_error_r
|
||
|
val ld_single_ecc_error_lo_r_ns = ld_single_ecc_error_lo_r & (io.lsu_commit_r | io.lsu_pkt_r.dma) & ~kill_ecc_corr_lo_r
|
||
|
val ld_single_ecc_error_hi_r_ns = ld_single_ecc_error_hi_r & (io.lsu_commit_r | io.lsu_pkt_r.dma) & ~kill_ecc_corr_hi_r
|
||
|
|
||
|
val lsu_double_ecc_error_r_ff = withClock(io.lsu_free_c2_clk){RegNext(io.lsu_double_ecc_error_r,0.U)}
|
||
|
val ld_single_ecc_error_hi_r_ff = withClock(io.lsu_free_c2_clk){RegNext(ld_single_ecc_error_hi_r_ns,0.U)}
|
||
|
val ld_single_ecc_error_lo_r_ff = withClock(io.lsu_free_c2_clk){RegNext(ld_single_ecc_error_lo_r_ns,0.U)}
|
||
|
|
||
|
val ld_sec_addr_hi_r_ff = rvdffe(io.end_addr_r(pt1.DCCM_BITS-1,0),io.ld_single_ecc_error_r.asBool,clock,io.scan_mode.asBool)
|
||
|
val ld_sec_addr_lo_r_ff = rvdffe(io.lsu_addr_r(pt1.DCCM_BITS-1,0),io.ld_single_ecc_error_r.asBool,clock,io.scan_mode.asBool)
|
||
|
val lsu_dccm_rden_d = io.lsu_pkt_d.valid & (io.lsu_pkt_d.load | (io.lsu_pkt_d.store & (~(io.lsu_pkt_d.word | io.lsu_pkt_d.dword) | (io.lsu_addr_d(1,0) =/= 0.U(2.W))))) & io.addr_in_dccm_d
|
||
|
val lsu_dccm_wren_d = io.dma_dccm_wen
|
||
|
|
||
|
io.ld_single_ecc_error_r_ff := (ld_single_ecc_error_lo_r_ff | ld_single_ecc_error_hi_r_ff) & ~lsu_double_ecc_error_r_ff
|
||
|
io.lsu_stbuf_commit_any := io.stbuf_reqvld_any & (~(lsu_dccm_rden_d | lsu_dccm_wren_d | io.ld_single_ecc_error_r_ff) |
|
||
|
(lsu_dccm_rden_d & ~((io.stbuf_addr_any(pt1.DCCM_WIDTH_BITS+pt1.DCCM_BANK_BITS-1,pt1.DCCM_WIDTH_BITS) === io.lsu_addr_d(pt1.DCCM_WIDTH_BITS+pt1.DCCM_BANK_BITS-1,pt1.DCCM_WIDTH_BITS)).asUInt |
|
||
|
(io.stbuf_addr_any(pt1.DCCM_WIDTH_BITS+pt1.DCCM_BANK_BITS-1,pt1.DCCM_WIDTH_BITS) === io.end_addr_d(pt1.DCCM_WIDTH_BITS+pt1.DCCM_BANK_BITS-1,pt1.DCCM_WIDTH_BITS)).asUInt)))
|
||
|
|
||
|
|
||
|
//DCCM inputs
|
||
|
io.dccm_wren := lsu_dccm_wren_d | io.lsu_stbuf_commit_any | io.ld_single_ecc_error_r_ff
|
||
|
io.dccm_rden := lsu_dccm_rden_d & io.addr_in_dccm_d
|
||
|
|
||
|
io.dccm_wr_addr_lo := Mux(io.ld_single_ecc_error_r_ff.asBool,
|
||
|
Mux(ld_single_ecc_error_lo_r_ff===1.U,ld_sec_addr_lo_r_ff(pt1.DCCM_BITS-1,0),ld_sec_addr_hi_r_ff(pt1.DCCM_BITS-1,0)),
|
||
|
Mux(lsu_dccm_wren_d.asBool,io.lsu_addr_d(pt1.DCCM_BITS-1,0),io.stbuf_addr_any(pt1.DCCM_BITS-1,0)))
|
||
|
|
||
|
io.dccm_wr_addr_hi := Mux(io.ld_single_ecc_error_r_ff.asBool,
|
||
|
Mux(ld_single_ecc_error_hi_r_ff===1.U, ld_sec_addr_hi_r_ff(pt1.DCCM_BITS-1,0), ld_sec_addr_lo_r_ff(pt1.DCCM_BITS-1,0)),
|
||
|
Mux(lsu_dccm_wren_d.asBool, io.end_addr_d(pt1.DCCM_BITS-1,0),io.stbuf_addr_any(pt1.DCCM_BITS-1,0)))
|
||
|
|
||
|
io.dccm_rd_addr_lo := io.lsu_addr_d(pt1.DCCM_BITS-1,0)
|
||
|
io.dccm_rd_addr_hi := io.end_addr_d(pt1.DCCM_BITS-1,0)
|
||
|
|
||
|
io.dccm_wr_data_lo := Mux(io.ld_single_ecc_error_r_ff.asBool,
|
||
|
Mux(ld_single_ecc_error_lo_r_ff===0.U,Cat(io.sec_data_ecc_lo_r_ff(pt1.DCCM_ECC_WIDTH-1,0),io.sec_data_lo_r_ff(pt1.DCCM_DATA_WIDTH-1,0)) ,
|
||
|
Cat(io.sec_data_ecc_hi_r_ff(pt1.DCCM_ECC_WIDTH-1,0),io.sec_data_hi_r_ff(pt1.DCCM_DATA_WIDTH-1,0))) ,
|
||
|
Mux(io.dma_dccm_wen.asBool,Cat(io.dma_dccm_wdata_ecc_lo(pt1.DCCM_ECC_WIDTH-1,0),io.dma_dccm_wdata_lo(pt1.DCCM_DATA_WIDTH-1,0)),
|
||
|
Cat(io.stbuf_ecc_any(pt1.DCCM_ECC_WIDTH-1,0),io.stbuf_data_any(pt1.DCCM_DATA_WIDTH-1,0))))
|
||
|
|
||
|
io.dccm_wr_data_hi := Mux(io.ld_single_ecc_error_r_ff.asBool,
|
||
|
Mux(ld_single_ecc_error_hi_r_ff===0.U, Cat(io.sec_data_ecc_hi_r_ff(pt1.DCCM_ECC_WIDTH-1,0),io.sec_data_hi_r_ff(pt1.DCCM_DATA_WIDTH-1,0)),
|
||
|
Cat(io.sec_data_ecc_lo_r_ff(pt1.DCCM_ECC_WIDTH-1,0),io.sec_data_lo_r_ff(pt1.DCCM_DATA_WIDTH-1,0))),
|
||
|
Mux(io.dma_dccm_wen.asBool, Cat(io.dma_dccm_wdata_ecc_hi(pt1.DCCM_ECC_WIDTH-1,0),io.dma_dccm_wdata_hi(pt1.DCCM_DATA_WIDTH-1,0)),
|
||
|
Cat(io.stbuf_ecc_any(pt1.DCCM_ECC_WIDTH-1,0),io.stbuf_data_any(pt1.DCCM_DATA_WIDTH-1,0))))
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// DCCM outputs
|
||
|
val store_byteen_m = (Fill(4,io.lsu_pkt_m.store)) & ((Fill(4,io.lsu_pkt_m.by) & 1.U(4.W)) |
|
||
|
(Fill(4,io.lsu_pkt_m.half) & 3.U(4.W)) |
|
||
|
(Fill(4,io.lsu_pkt_m.word) & 15.U(4.W)))
|
||
|
|
||
|
val store_byteen_r = (Fill(4,io.lsu_pkt_r.store)) & ((Fill(4,io.lsu_pkt_r.by) & 1.U(4.W)) |
|
||
|
(Fill(4,io.lsu_pkt_r.half) & 3.U(4.W)) |
|
||
|
(Fill(4,io.lsu_pkt_r.word) & 15.U(4.W)))
|
||
|
val store_byteen_ext_m = WireInit(UInt(8.W),0.U)
|
||
|
store_byteen_ext_m := store_byteen_m(3,0) << io.lsu_addr_m(1,0) // The packet in m
|
||
|
val store_byteen_ext_r = WireInit(UInt(8.W),0.U)
|
||
|
store_byteen_ext_r := store_byteen_r(3,0) << io.lsu_addr_r(1,0)
|
||
|
|
||
|
//LM: If store buffer addr matches with the address in the m-stage then there will be bypassed
|
||
|
val dccm_wr_bypass_d_m_lo = (io.stbuf_addr_any(pt1.DCCM_BITS-1,2) === io.lsu_addr_m(pt1.DCCM_BITS-1,2)) & io.addr_in_dccm_m
|
||
|
val dccm_wr_bypass_d_m_hi = (io.stbuf_addr_any(pt1.DCCM_BITS-1,2) === io.end_addr_m(pt1.DCCM_BITS-1,2)) & io.addr_in_dccm_m
|
||
|
|
||
|
val dccm_wr_bypass_d_r_lo = (io.stbuf_addr_any(pt1.DCCM_BITS-1,2) === io.lsu_addr_r(pt1.DCCM_BITS-1,2)) & io.addr_in_dccm_r
|
||
|
val dccm_wr_bypass_d_r_hi = (io.stbuf_addr_any(pt1.DCCM_BITS-1,2) === io.end_addr_r(pt1.DCCM_BITS-1,2)) & io.addr_in_dccm_r
|
||
|
|
||
|
val dccm_wr_bypass_d_m_hi_Q = WireInit(0.U(1.W))
|
||
|
val dccm_wr_bypass_d_m_lo_Q = WireInit(0.U(1.W))
|
||
|
val dccm_wren_Q = WireInit(0.U(1.W))
|
||
|
val dccm_wr_data_Q = WireInit(0.U(32.W))
|
||
|
val store_data_pre_r = WireInit(0.U(64.W))
|
||
|
val store_data_pre_hi_r = WireInit(0.U(32.W))
|
||
|
val store_data_pre_lo_r = WireInit(0.U(32.W))
|
||
|
val store_data_pre_m = WireInit(0.U(64.W))
|
||
|
val store_data_hi_m = WireInit(0.U(32.W))
|
||
|
val store_data_lo_m = WireInit(0.U(32.W))
|
||
|
|
||
|
if(pt.LOAD_TO_USE_PLUS1 == 1){
|
||
|
store_data_pre_r := Cat(Fill(32,0.U),io.store_data_r(31,0)) << 8.U*io.lsu_addr_r(1,0)
|
||
|
store_data_pre_hi_r := store_data_pre_r(63,32)
|
||
|
store_data_pre_lo_r := store_data_pre_r(31, 0)
|
||
|
io.store_data_lo_r := Reverse(Cat(VecInit.tabulate(4)(i=> Reverse(Mux(store_byteen_ext_r(i).asBool, store_data_pre_lo_r((8*i)+7,8*i), Mux((dccm_wren_Q & dccm_wr_bypass_d_m_lo_Q).asBool, dccm_wr_data_Q((8*i)+7,8*i),io.sec_data_lo_r((8*i)+7,8*i)))))))
|
||
|
io.store_data_hi_r := Reverse(Cat(VecInit.tabulate(4)(i=> Reverse(Mux(store_byteen_ext_r(i+4).asBool,store_data_pre_hi_r((8*i)+7,8*i), Mux((dccm_wren_Q & dccm_wr_bypass_d_m_hi_Q).asBool, dccm_wr_data_Q((8*i)+7,8*i),io.sec_data_hi_r((8*i)+7,8*i)))))))
|
||
|
io.store_datafn_lo_r := Reverse(Cat(VecInit.tabulate(4)(i=> Reverse(Mux(store_byteen_ext_r(i).asBool, store_data_pre_lo_r((8*i)+7,8*i), Mux((io.lsu_stbuf_commit_any & dccm_wr_bypass_d_r_lo).asBool,io.stbuf_data_any((8*i)+7,(8*i)),Mux((dccm_wren_Q & dccm_wr_bypass_d_m_lo_Q).asBool, dccm_wr_data_Q((8*i)+7,8*i),io.sec_data_lo_r((8*i)+7,8*i))))))))
|
||
|
io.store_datafn_hi_r := Reverse(Cat(VecInit.tabulate(4)(i=> Reverse(Mux(store_byteen_ext_r(i+4).asBool,store_data_pre_hi_r((8*i)+7,8*i), Mux((io.lsu_stbuf_commit_any & dccm_wr_bypass_d_r_lo).asBool,io.stbuf_data_any((8*i)+7,(8*i)),Mux((dccm_wren_Q & dccm_wr_bypass_d_m_hi_Q).asBool, dccm_wr_data_Q((8*i)+7,8*i),io.sec_data_hi_r((8*i)+7,8*i))))))))
|
||
|
dccm_wren_Q := withClock(io.lsu_free_c2_clk){RegNext(io.lsu_stbuf_commit_any,0.U)}
|
||
|
dccm_wr_data_Q := rvdffe(io.stbuf_data_any,io.lsu_stbuf_commit_any.asBool,clock,io.scan_mode.asBool)
|
||
|
dccm_wr_bypass_d_m_lo_Q := withClock(io.lsu_free_c2_clk){RegNext(dccm_wr_bypass_d_m_lo,0.U)}
|
||
|
dccm_wr_bypass_d_m_hi_Q := withClock(io.lsu_free_c2_clk){RegNext(dccm_wr_bypass_d_m_hi,0.U)}
|
||
|
io.store_data_r := withClock(io.lsu_store_c1_r_clk){RegNext(io.store_data_m,0.U)}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
store_data_pre_m := Cat(Fill(32,0.U),io.store_data_m(31,0)) << 8.U*io.lsu_addr_m(1,0)
|
||
|
store_data_hi_m := store_data_pre_m(63,32)
|
||
|
store_data_lo_m := store_data_pre_m(31, 0)
|
||
|
io.store_data_lo_r := withClock(io.lsu_store_c1_r_clk){RegNext(Reverse(Cat(VecInit.tabulate(4)(i=> Reverse(Mux(store_byteen_ext_m(i).asBool, store_data_lo_m((8*i)+7,8*i), Mux((io.lsu_stbuf_commit_any & dccm_wr_bypass_d_m_lo).asBool, io.stbuf_data_any((8*i)+7,8*i),io.sec_data_lo_m((8*i)+7,8*i))))))),0.U)}
|
||
|
io.store_data_hi_r := withClock(io.lsu_store_c1_r_clk){RegNext(Reverse(Cat(VecInit.tabulate(4)(i=> Reverse(Mux(store_byteen_ext_m(i+4).asBool,store_data_hi_m((8*i)+7,8*i), Mux((io.lsu_stbuf_commit_any & dccm_wr_bypass_d_m_hi).asBool, io.stbuf_data_any((8*i)+7,8*i),io.sec_data_hi_m((8*i)+7,8*i))))))),0.U)}
|
||
|
io.store_datafn_lo_r := Reverse(Cat(VecInit.tabulate(4)(i=> Reverse(Mux((io.lsu_stbuf_commit_any & dccm_wr_bypass_d_r_lo & ~store_byteen_ext_r(i)).asBool,io.stbuf_data_any((8*i)+7,8*i),io.store_data_lo_r((8*i)+7,8*i))))))
|
||
|
io.store_datafn_hi_r := Reverse(Cat(VecInit.tabulate(4)(i=> Reverse(Mux((io.lsu_stbuf_commit_any & dccm_wr_bypass_d_r_lo & ~store_byteen_ext_r(i)).asBool,io.stbuf_data_any((8*i)+7,8*i),io.store_data_hi_r((8*i)+7,8*i))))))
|
||
|
io.store_data_r := (Cat(io.store_data_hi_r(31,0),io.store_data_lo_r(31,0)) >> 8.U*io.lsu_addr_r(1,0)) & Reverse(Cat(VecInit.tabulate(4)(i=> Fill(8,store_byteen_r(i)))))
|
||
|
}
|
||
|
io.dccm_rdata_lo_m := io.dccm_rd_data_lo(pt1.DCCM_DATA_WIDTH-1,0) //4 lines
|
||
|
io.dccm_rdata_hi_m := io.dccm_rd_data_hi(pt1.DCCM_DATA_WIDTH-1,0)
|
||
|
io.dccm_data_ecc_lo_m := io.dccm_rd_data_lo(pt1.DCCM_FDATA_WIDTH-1,pt1.DCCM_DATA_WIDTH)
|
||
|
io.dccm_data_ecc_hi_m := io.dccm_rd_data_hi(pt1.DCCM_FDATA_WIDTH-1,pt1.DCCM_DATA_WIDTH)
|
||
|
|
||
|
io.picm_wren := (io.lsu_pkt_r.valid & io.lsu_pkt_r.store & io.addr_in_pic_r & io.lsu_commit_r) | io.dma_pic_wen
|
||
|
io.picm_rden := io.lsu_pkt_d.valid & io.lsu_pkt_d.load & io.addr_in_pic_d
|
||
|
io.picm_mken := io.lsu_pkt_d.valid & io.lsu_pkt_d.store & io.addr_in_pic_d
|
||
|
io.picm_rdaddr := pt.PIC_BASE_ADDR | Cat(Fill(32-pt1.PIC_BITS,0.U),io.lsu_addr_d(pt1.PIC_BITS-1,0))
|
||
|
io.picm_wraddr := pt.PIC_BASE_ADDR | Cat(Fill(32-pt1.PIC_BITS,0.U),Mux(io.dma_pic_wen.asBool,io.dma_mem_addr(pt1.PIC_BITS-1,0),io.lsu_addr_r(pt1.PIC_BITS-1,0)))
|
||
|
io.picm_mask_data_m := picm_rd_data_m(31,0)
|
||
|
io.picm_wr_data := Mux(io.dma_pic_wen.asBool,io.dma_mem_wdata(31,0),io.store_datafn_lo_r(31,0))
|
||
|
|
||
|
if(pt1.DCCM_ENABLE == 1){
|
||
|
io.lsu_dccm_rden_m := withClock(io.lsu_c2_m_clk){RegNext(lsu_dccm_rden_d,0.U)}
|
||
|
io.lsu_dccm_rden_r := withClock(io.lsu_c2_r_clk){RegNext(io.lsu_dccm_rden_m,0.U)}
|
||
|
}
|
||
|
else{
|
||
|
io.lsu_dccm_rden_m := 0.U
|
||
|
io.lsu_dccm_rden_r := 0.U}
|
||
|
|
||
|
|
||
|
//io.dccm_wr_addr_lo := 0.U
|
||
|
//io.dccm_wr_addr_hi := 0.U
|
||
|
//io.dccm_rd_addr_lo := 0.U
|
||
|
//io.dccm_rd_addr_hi := 0.U
|
||
|
//io.dccm_wr_data_lo := 0.U
|
||
|
//io.dccm_wr_data_hi := 0.U
|
||
|
|
||
|
// io.dccm_rdata_hi_m := 0.U
|
||
|
// io.dccm_rdata_lo_m := 0.U
|
||
|
// io.dccm_data_ecc_hi_m := 0.U
|
||
|
// io.dccm_data_ecc_lo_m := 0.U
|
||
|
//io.lsu_ld_data_m := 0.U
|
||
|
|
||
|
//io.store_data_hi_r := 0.U
|
||
|
//io.store_data_lo_r := 0.U
|
||
|
//io.store_datafn_hi_r := 0.U
|
||
|
//io.store_datafn_lo_r := 0.U
|
||
|
// io.store_data_r := 0.U
|
||
|
//io.ld_single_ecc_error_r := 0.U
|
||
|
//io.ld_single_ecc_error_r_ff := 0.U
|
||
|
//io.picm_mask_data_m := 0.U
|
||
|
//io.lsu_stbuf_commit_any := 0.U
|
||
|
// io.lsu_dccm_rden_m := 0.U
|
||
|
// io.lsu_dccm_rden_r := 0.U
|
||
|
//io.dccm_dma_rvalid := 0.U
|
||
|
//io.dccm_dma_ecc_error := 0.U
|
||
|
//io.dccm_dma_rtag := 0.U
|
||
|
//io.dccm_dma_rdata := 0.U
|
||
|
//io.dccm_wren := 0.U
|
||
|
//io.dccm_rden := 0.U
|
||
|
//io.dccm_wr_addr_lo := 0.U
|
||
|
//io.dccm_wr_data_lo := 0.U
|
||
|
//io.dccm_wr_addr_hi := 0.U
|
||
|
//io.dccm_wr_data_hi := 0.U
|
||
|
//io.dccm_rd_addr_hi := 0.U
|
||
|
//io.dccm_rd_data_hi := 0.U
|
||
|
//io.picm_wren := 0.U
|
||
|
//io.picm_rden := 0.U
|
||
|
//io.picm_mken := 0.U
|
||
|
//io.picm_rdaddr := 0.U
|
||
|
//io.picm_wraddr := 0.U
|
||
|
//io.picm_wr_data := 0.U
|
||
|
//io.picm_rd_data := 0.U
|
||
|
}
|
||
|
|
||
|
object dccm_ctl extends App{
|
||
|
println("Generate Verilog")
|
||
|
chisel3.Driver.execute(args, ()=> new el2_lsu_dccm_ctl)
|
||
|
}
|
||
|
|