quasar/src/main/scala/lsu/el2_lsu_ecc.scala

165 lines
8.7 KiB
Scala

package lsu
import chisel3._
import chisel3.util._
import chisel3.experimental.chiselName
import include._
import lib._
@chiselName
class el2_lsu_ecc extends Module with el2_lib with RequireAsyncReset {
val io = IO(new Bundle{
val lsu_c2_r_clk = Input(Clock())
val lsu_pkt_m = Flipped(Valid(new el2_lsu_pkt_t))
val lsu_pkt_r = Flipped(Valid(new el2_lsu_pkt_t))
val stbuf_data_any = Input(UInt(DCCM_DATA_WIDTH.W))
val dec_tlu_core_ecc_disable = Input(Bool())
val lsu_dccm_rden_r = Input(Bool())
val addr_in_dccm_r = Input(Bool())
val lsu_addr_r = Input(UInt(DCCM_BITS.W))
val end_addr_r = Input(UInt(DCCM_BITS.W))
val lsu_addr_m = Input(UInt(DCCM_BITS.W))
val end_addr_m = Input(UInt(DCCM_BITS.W))
val dccm_rdata_hi_r = Input(UInt(DCCM_DATA_WIDTH.W))
val dccm_rdata_lo_r = Input(UInt(DCCM_DATA_WIDTH.W))
val dccm_rdata_hi_m = Input(UInt(DCCM_DATA_WIDTH.W))
val dccm_rdata_lo_m = Input(UInt(DCCM_DATA_WIDTH.W))
val dccm_data_ecc_hi_r = Input(UInt(DCCM_ECC_WIDTH.W))
val dccm_data_ecc_lo_r = Input(UInt(DCCM_ECC_WIDTH.W))
val dccm_data_ecc_hi_m = Input(UInt(DCCM_ECC_WIDTH.W))
val dccm_data_ecc_lo_m = Input(UInt(DCCM_ECC_WIDTH.W))
val ld_single_ecc_error_r = Input(Bool())
val ld_single_ecc_error_r_ff = Input(Bool())
val lsu_dccm_rden_m = Input(Bool())
val addr_in_dccm_m = Input(Bool())
val dma_dccm_wen = Input(Bool())
val dma_dccm_wdata_lo = Input(UInt(32.W))
val dma_dccm_wdata_hi = Input(UInt(32.W))
val scan_mode = Input(Bool())
//Outputs
val sec_data_hi_r = Output(UInt(DCCM_DATA_WIDTH.W))
val sec_data_lo_r = Output(UInt(DCCM_DATA_WIDTH.W))
val sec_data_hi_m = Output(UInt(DCCM_DATA_WIDTH.W))
val sec_data_lo_m = Output(UInt(DCCM_DATA_WIDTH.W))
val sec_data_hi_r_ff = Output(UInt(DCCM_DATA_WIDTH.W))
val sec_data_lo_r_ff = Output(UInt(DCCM_DATA_WIDTH.W))
val dma_dccm_wdata_ecc_hi = Output(UInt(DCCM_ECC_WIDTH.W))
val dma_dccm_wdata_ecc_lo = Output(UInt(DCCM_ECC_WIDTH.W))
val stbuf_ecc_any = Output(UInt(DCCM_ECC_WIDTH.W))
val sec_data_ecc_hi_r_ff = Output(UInt(DCCM_ECC_WIDTH.W))
val sec_data_ecc_lo_r_ff = Output(UInt(DCCM_ECC_WIDTH.W))
val single_ecc_error_hi_r = Output(Bool())
val single_ecc_error_lo_r = Output(Bool())
val lsu_single_ecc_error_r = Output(Bool())
val lsu_double_ecc_error_r = Output(Bool())
val lsu_single_ecc_error_m = Output(Bool())
val lsu_double_ecc_error_m = Output(Bool())
})
val is_ldst_r = WireInit(Bool(),init = 0.U)
val is_ldst_hi_any = WireInit(Bool(),init = 0.U)
val is_ldst_lo_any = WireInit(Bool(),init = 0.U)
val dccm_wdata_hi_any = WireInit(0.U(DCCM_DATA_WIDTH.W))
val dccm_wdata_lo_any = WireInit(0.U(DCCM_DATA_WIDTH.W))
val dccm_rdata_hi_any = WireInit(0.U(DCCM_DATA_WIDTH.W))
val dccm_rdata_lo_any = WireInit(0.U(DCCM_DATA_WIDTH.W))
// val dccm_wdata_ecc_hi_any = WireInit(0.U(DCCM_ECC_WIDTH.W))
//val dccm_wdata_ecc_lo_any = WireInit(0.U(DCCM_ECC_WIDTH.W))
val dccm_data_ecc_hi_any = WireInit(0.U(DCCM_ECC_WIDTH.W))
val dccm_data_ecc_lo_any = WireInit(0.U(DCCM_ECC_WIDTH.W))
val double_ecc_error_hi_m = WireInit(Bool(),init = 0.U)
val double_ecc_error_lo_m = WireInit(Bool(),init = 0.U)
val double_ecc_error_hi_r = WireInit(Bool(),init = 0.U)
val double_ecc_error_lo_r = WireInit(Bool(),init = 0.U)
val ldst_dual_m = WireInit(Bool(),init = 0.U)
val ldst_dual_r = WireInit(Bool(),init = 0.U)
val is_ldst_m = WireInit(Bool(),init = 0.U)
val is_ldst_hi_m = WireInit(Bool(),init = 0.U)
val is_ldst_lo_m = WireInit(Bool(),init = 0.U)
val is_ldst_hi_r = WireInit(Bool(),init = 0.U)
val is_ldst_lo_r = WireInit(Bool(),init = 0.U)
io.sec_data_hi_m :=0.U
io.sec_data_lo_m :=0.U
io.lsu_single_ecc_error_m :=0.U
io.lsu_double_ecc_error_m :=0.U
//////////////////////////////CODE STARTS HERE///////////////////////
val (ecc_out_hi_nc, sec_data_hi_any, single_ecc_error_hi_any, double_ecc_error_hi_any) = if(DCCM_ENABLE)
rvecc_decode(is_ldst_hi_any, dccm_rdata_hi_any, dccm_data_ecc_hi_any, 0.U) else (0.U, 0.U, 0.U, 0.U)
val ( ecc_out_lo_nc, sec_data_lo_any, single_ecc_error_lo_any, double_ecc_error_lo_any) = if(DCCM_ENABLE)
rvecc_decode(is_ldst_lo_any, dccm_rdata_lo_any, dccm_data_ecc_lo_any, 0.U) else (0.U, 0.U, 0.U, 0.U)
val dccm_wdata_ecc_lo_any = if(DCCM_ENABLE) rvecc_encode(dccm_wdata_lo_any) else (0.U)
val dccm_wdata_ecc_hi_any = if(DCCM_ENABLE) rvecc_encode(dccm_wdata_hi_any) else (0.U)
when (LOAD_TO_USE_PLUS1.B) {
ldst_dual_r := io.lsu_addr_r(2) =/= io.end_addr_r(2)
is_ldst_r := io.lsu_pkt_r.valid & (io.lsu_pkt_r.bits.load | io.lsu_pkt_r.bits.store) & io.addr_in_dccm_r & io.lsu_dccm_rden_r
is_ldst_lo_r := is_ldst_r & !io.dec_tlu_core_ecc_disable
is_ldst_hi_r := is_ldst_r & (ldst_dual_r | io.lsu_pkt_r.bits.dma) & !io.dec_tlu_core_ecc_disable
is_ldst_hi_any := is_ldst_hi_r
dccm_rdata_hi_any := io.dccm_rdata_hi_r
dccm_data_ecc_hi_any := io.dccm_data_ecc_hi_r
is_ldst_lo_any := is_ldst_lo_r
dccm_rdata_lo_any := io.dccm_rdata_lo_r
dccm_data_ecc_lo_any := io.dccm_data_ecc_lo_r
io.sec_data_hi_r := sec_data_hi_any;
io.single_ecc_error_hi_r := single_ecc_error_hi_any
double_ecc_error_hi_r := double_ecc_error_hi_any
io.sec_data_lo_r := sec_data_lo_any
io.single_ecc_error_lo_r := single_ecc_error_lo_any
double_ecc_error_lo_r := double_ecc_error_lo_any
io.lsu_single_ecc_error_r := io.single_ecc_error_hi_r | io.single_ecc_error_lo_r;
io.lsu_double_ecc_error_r := double_ecc_error_hi_r | double_ecc_error_lo_r
}
.otherwise {
ldst_dual_m := io.lsu_addr_m(2) =/= io.end_addr_m(2)
is_ldst_m := io.lsu_pkt_m.valid & (io.lsu_pkt_m.bits.load | io.lsu_pkt_m.bits.store) & io.addr_in_dccm_m & io.lsu_dccm_rden_m
is_ldst_lo_m := is_ldst_m & !io.dec_tlu_core_ecc_disable
is_ldst_hi_m := is_ldst_m & (ldst_dual_m | io.lsu_pkt_m.bits.dma) & !io.dec_tlu_core_ecc_disable
is_ldst_hi_any := is_ldst_hi_m
dccm_rdata_hi_any := io.dccm_rdata_hi_m
dccm_data_ecc_hi_any := io.dccm_data_ecc_hi_m
is_ldst_lo_any := is_ldst_lo_m
dccm_rdata_lo_any := io.dccm_rdata_lo_m
dccm_data_ecc_lo_any := io.dccm_data_ecc_lo_m
io.sec_data_hi_m := sec_data_hi_any
double_ecc_error_hi_m := double_ecc_error_hi_any
io.sec_data_lo_m := sec_data_lo_any
double_ecc_error_lo_m := double_ecc_error_lo_any
io.lsu_single_ecc_error_m := single_ecc_error_hi_any | single_ecc_error_lo_any;
io.lsu_double_ecc_error_m := double_ecc_error_hi_m | double_ecc_error_lo_m
withClock(io.lsu_c2_r_clk) {io.lsu_single_ecc_error_r := RegNext(io.lsu_single_ecc_error_m,0.U)}
withClock(io.lsu_c2_r_clk) {io.lsu_double_ecc_error_r := RegNext(io.lsu_double_ecc_error_m,0.U)}
withClock(io.lsu_c2_r_clk) {io.single_ecc_error_lo_r := RegNext(single_ecc_error_lo_any,0.U)}
withClock(io.lsu_c2_r_clk) {io.single_ecc_error_hi_r := RegNext(single_ecc_error_hi_any,0.U)}
withClock(io.lsu_c2_r_clk) {io.sec_data_hi_r := RegNext(io.sec_data_hi_m,0.U)}
withClock(io.lsu_c2_r_clk) {io.sec_data_lo_r := RegNext(io.sec_data_lo_m,0.U)}
}
// Logic for ECC generation during write
dccm_wdata_lo_any := Mux(io.ld_single_ecc_error_r_ff.asBool, io.sec_data_lo_r_ff,Mux(io.dma_dccm_wen.asBool, io.dma_dccm_wdata_lo, io.stbuf_data_any))
dccm_wdata_hi_any := Mux(io.ld_single_ecc_error_r_ff.asBool, io.sec_data_hi_r_ff,Mux(io.dma_dccm_wen.asBool, io.dma_dccm_wdata_hi, io.stbuf_data_any))
io.sec_data_ecc_hi_r_ff := dccm_wdata_ecc_hi_any
io.sec_data_ecc_lo_r_ff := dccm_wdata_ecc_lo_any
io.stbuf_ecc_any := dccm_wdata_ecc_lo_any
io.dma_dccm_wdata_ecc_hi := dccm_wdata_ecc_hi_any
io.dma_dccm_wdata_ecc_lo := dccm_wdata_ecc_lo_any
io.sec_data_hi_r_ff := rvdffe(io.sec_data_hi_r, io.ld_single_ecc_error_r,clock,io.scan_mode)
io.sec_data_lo_r_ff := rvdffe(io.sec_data_lo_r, io.ld_single_ecc_error_r,clock,io.scan_mode)
}
object eccmain extends App{
println("Generate Verilog")
println((new chisel3.stage.ChiselStage).emitVerilog(new el2_lsu_ecc()))
}