Update el2_lsu_addrcheck.scala
This commit is contained in:
parent
2da85e1800
commit
5cc210e06d
|
@ -1,10 +1,22 @@
|
||||||
|
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
|
||||||
|
|
||||||
class el2_lsu_addrcheck extends Module
|
class el2_lsu_addrcheck extends Module
|
||||||
{
|
{val io = IO(new Bundle{
|
||||||
val io = IO(new Bundle{
|
|
||||||
val lsu_c2_m_clk = Input(Clock())
|
val lsu_c2_m_clk = Input(Clock())
|
||||||
//val rst_l = IO(Input(1.W)) //implicit
|
|
||||||
val start_addr_d = Input(UInt(32.W))
|
val start_addr_d = Input(UInt(32.W))
|
||||||
val end_addr_d = Input(UInt(32.W))
|
val end_addr_d = Input(UInt(32.W))
|
||||||
val lsu_pkt_d = Input(new el2_lsu_pkt_t)
|
val lsu_pkt_d = Input(new el2_lsu_pkt_t)
|
||||||
|
@ -20,8 +32,7 @@ class el2_lsu_addrcheck extends Module
|
||||||
val exc_mscause_d = Output(UInt(4.W))
|
val exc_mscause_d = Output(UInt(4.W))
|
||||||
val fir_dccm_access_error_d = Output(UInt(1.W))
|
val fir_dccm_access_error_d = Output(UInt(1.W))
|
||||||
val fir_nondccm_access_error_d = Output(UInt(1.W))
|
val fir_nondccm_access_error_d = Output(UInt(1.W))
|
||||||
val scan_mode = Input(UInt(1.W))
|
val scan_mode = Input(UInt(1.W))})
|
||||||
})
|
|
||||||
|
|
||||||
val start_addr_in_dccm_d = WireInit(0.U(1.W))
|
val start_addr_in_dccm_d = WireInit(0.U(1.W))
|
||||||
val start_addr_in_dccm_region_d = WireInit(0.U(1.W))
|
val start_addr_in_dccm_region_d = WireInit(0.U(1.W))
|
||||||
|
@ -84,7 +95,7 @@ class el2_lsu_addrcheck extends Module
|
||||||
|
|
||||||
val non_dccm_access_ok = (~(Cat(pt.DATA_ACCESS_ENABLE0,pt.DATA_ACCESS_ENABLE1,pt.DATA_ACCESS_ENABLE2,pt.DATA_ACCESS_ENABLE3,
|
val non_dccm_access_ok = (~(Cat(pt.DATA_ACCESS_ENABLE0,pt.DATA_ACCESS_ENABLE1,pt.DATA_ACCESS_ENABLE2,pt.DATA_ACCESS_ENABLE3,
|
||||||
pt.DATA_ACCESS_ENABLE4,pt.DATA_ACCESS_ENABLE5,pt.DATA_ACCESS_ENABLE6,pt.DATA_ACCESS_ENABLE7)).orR) |
|
pt.DATA_ACCESS_ENABLE4,pt.DATA_ACCESS_ENABLE5,pt.DATA_ACCESS_ENABLE6,pt.DATA_ACCESS_ENABLE7)).orR) |
|
||||||
(((pt.DATA_ACCESS_ENABLE0 & ((io.start_addr_d(31,0) | pt.DATA_ACCESS_MASK0)) === (pt.DATA_ACCESS_ADDR0 | pt.DATA_ACCESS_MASK0)) | //0111
|
(((pt.DATA_ACCESS_ENABLE0 & ((io.start_addr_d(31,0) | pt.DATA_ACCESS_MASK0)) === (pt.DATA_ACCESS_ADDR0 | pt.DATA_ACCESS_MASK0)) | //0111
|
||||||
(pt.DATA_ACCESS_ENABLE1 & ((io.start_addr_d(31,0) | pt.DATA_ACCESS_MASK1)) === (pt.DATA_ACCESS_ADDR1 | pt.DATA_ACCESS_MASK1)) | //1111
|
(pt.DATA_ACCESS_ENABLE1 & ((io.start_addr_d(31,0) | pt.DATA_ACCESS_MASK1)) === (pt.DATA_ACCESS_ADDR1 | pt.DATA_ACCESS_MASK1)) | //1111
|
||||||
(pt.DATA_ACCESS_ENABLE2 & ((io.start_addr_d(31,0) | pt.DATA_ACCESS_MASK2)) === (pt.DATA_ACCESS_ADDR2 | pt.DATA_ACCESS_MASK2)) | //1011
|
(pt.DATA_ACCESS_ENABLE2 & ((io.start_addr_d(31,0) | pt.DATA_ACCESS_MASK2)) === (pt.DATA_ACCESS_ADDR2 | pt.DATA_ACCESS_MASK2)) | //1011
|
||||||
(pt.DATA_ACCESS_ENABLE3 & ((io.start_addr_d(31,0) | pt.DATA_ACCESS_MASK3)) === (pt.DATA_ACCESS_ADDR3 | pt.DATA_ACCESS_MASK3)) | //1000
|
(pt.DATA_ACCESS_ENABLE3 & ((io.start_addr_d(31,0) | pt.DATA_ACCESS_MASK3)) === (pt.DATA_ACCESS_ADDR3 | pt.DATA_ACCESS_MASK3)) | //1000
|
||||||
|
@ -103,13 +114,10 @@ class el2_lsu_addrcheck extends Module
|
||||||
(pt.DATA_ACCESS_ENABLE7 & ((io.end_addr_d(31,0) | pt.DATA_ACCESS_MASK7)) === (pt.DATA_ACCESS_ADDR7 | pt.DATA_ACCESS_MASK7))))
|
(pt.DATA_ACCESS_ENABLE7 & ((io.end_addr_d(31,0) | pt.DATA_ACCESS_MASK7)) === (pt.DATA_ACCESS_ADDR7 | pt.DATA_ACCESS_MASK7))))
|
||||||
|
|
||||||
val regpred_access_fault_d = (start_addr_dccm_or_pic ^ base_reg_dccm_or_pic)
|
val regpred_access_fault_d = (start_addr_dccm_or_pic ^ base_reg_dccm_or_pic)
|
||||||
val picm_access_fault_d = (io.addr_in_pic_d & ((io.start_addr_d(1,0) != "b00".U) | ~io.lsu_pkt_d.word))
|
val picm_access_fault_d = (io.addr_in_pic_d & ((io.start_addr_d(1,0) != 0.U(2.W)) | ~io.lsu_pkt_d.word))
|
||||||
|
|
||||||
|
|
||||||
val unmapped_access_fault_d = WireInit(1.U(1.W))
|
val unmapped_access_fault_d = WireInit(1.U(1.W))
|
||||||
val mpu_access_fault_d = WireInit(1.U(1.W))
|
val mpu_access_fault_d = WireInit(1.U(1.W))
|
||||||
|
|
||||||
|
|
||||||
if(pt1.DCCM_REGION == pt1.PIC_REGION){
|
if(pt1.DCCM_REGION == pt1.PIC_REGION){
|
||||||
unmapped_access_fault_d := ((start_addr_in_dccm_region_d & ~(start_addr_in_dccm_d | start_addr_in_pic_d)) |
|
unmapped_access_fault_d := ((start_addr_in_dccm_region_d & ~(start_addr_in_dccm_d | start_addr_in_pic_d)) |
|
||||||
// 0. Addr in dccm/pic region but not in dccm/pic offset
|
// 0. Addr in dccm/pic region but not in dccm/pic offset
|
||||||
|
@ -119,76 +127,33 @@ class el2_lsu_addrcheck extends Module
|
||||||
// 0. DCCM -> PIC cross when DCCM/PIC in same region
|
// 0. DCCM -> PIC cross when DCCM/PIC in same region
|
||||||
(start_addr_in_pic_d & end_addr_in_dccm_d))
|
(start_addr_in_pic_d & end_addr_in_dccm_d))
|
||||||
// 0. DCCM -> PIC cross when DCCM/PIC in same region
|
// 0. DCCM -> PIC cross when DCCM/PIC in same region
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mpu_access_fault_d := (~start_addr_in_dccm_region_d & ~non_dccm_access_ok)
|
mpu_access_fault_d := (~start_addr_in_dccm_region_d & ~non_dccm_access_ok)
|
||||||
// 3. Address is not in a populated non-dccm region
|
// 3. Address is not in a populated non-dccm region
|
||||||
}
|
}
|
||||||
|
|
||||||
else{
|
else{
|
||||||
|
unmapped_access_fault_d := ((start_addr_in_dccm_region_d & ~start_addr_in_dccm_d) | (end_addr_in_dccm_region_d & ~end_addr_in_dccm_d) |
|
||||||
unmapped_access_fault_d := ((start_addr_in_dccm_region_d & ~start_addr_in_dccm_d) |
|
(start_addr_in_pic_region_d & ~start_addr_in_pic_d) | (end_addr_in_pic_region_d & ~end_addr_in_pic_d))
|
||||||
// 0. Addr in dccm region but not in dccm offset
|
|
||||||
(end_addr_in_dccm_region_d & ~end_addr_in_dccm_d) |
|
|
||||||
// 0. Addr in dccm region but not in dccm offset
|
|
||||||
(start_addr_in_pic_region_d & ~start_addr_in_pic_d) |
|
|
||||||
// 0. Addr in picm region but not in picm offset
|
|
||||||
(end_addr_in_pic_region_d & ~end_addr_in_pic_d))
|
|
||||||
|
|
||||||
// 0. Addr in picm region but not in picm offset
|
|
||||||
|
|
||||||
|
|
||||||
mpu_access_fault_d := (~start_addr_in_pic_region_d & ~start_addr_in_dccm_region_d & ~non_dccm_access_ok);
|
mpu_access_fault_d := (~start_addr_in_pic_region_d & ~start_addr_in_dccm_region_d & ~non_dccm_access_ok);
|
||||||
// 3. Address is not in a populated non-dccm region
|
// 3. Address is not in a populated non-dccm region
|
||||||
}
|
}
|
||||||
|
|
||||||
//check width of access_fault_mscause_d
|
//check width of access_fault_mscause_d
|
||||||
|
|
||||||
io.access_fault_d := (unmapped_access_fault_d | mpu_access_fault_d | picm_access_fault_d | regpred_access_fault_d) & io.lsu_pkt_d.valid & ~io.lsu_pkt_d.dma
|
io.access_fault_d := (unmapped_access_fault_d | mpu_access_fault_d | picm_access_fault_d | regpred_access_fault_d) & io.lsu_pkt_d.valid & ~io.lsu_pkt_d.dma
|
||||||
val access_fault_mscause_d = WireInit(0.U(4.W))
|
val access_fault_mscause_d = Mux(unmapped_access_fault_d.asBool,2.U(4.W), Mux(mpu_access_fault_d.asBool,3.U(4.W), Mux(regpred_access_fault_d.asBool,5.U(4.W), Mux(picm_access_fault_d.asBool,6.U(4.W),0.U(4.W)))))
|
||||||
access_fault_mscause_d := Mux(unmapped_access_fault_d.asBool, "b0010".U, Mux(mpu_access_fault_d.asBool, "b0011".U, Mux(regpred_access_fault_d.asBool, "b0101".U, Mux(picm_access_fault_d.asBool, "b0110".U, "b0000".U))))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val regcross_misaligned_fault_d = (io.start_addr_d(31,28) =/= io.end_addr_d(31,28))
|
val regcross_misaligned_fault_d = (io.start_addr_d(31,28) =/= io.end_addr_d(31,28))
|
||||||
val sideeffect_misaligned_fault_d = (is_sideeffects_d & ~ is_aligned_d)
|
val sideeffect_misaligned_fault_d = (is_sideeffects_d & ~ is_aligned_d)
|
||||||
|
|
||||||
|
|
||||||
io.misaligned_fault_d := (regcross_misaligned_fault_d | (sideeffect_misaligned_fault_d & io.addr_external_d)) & io.lsu_pkt_d.valid & ~io.lsu_pkt_d.dma
|
io.misaligned_fault_d := (regcross_misaligned_fault_d | (sideeffect_misaligned_fault_d & io.addr_external_d)) & io.lsu_pkt_d.valid & ~io.lsu_pkt_d.dma
|
||||||
|
val misaligned_fault_mscause_d = Mux(regcross_misaligned_fault_d,2.U(4.W),Mux(sideeffect_misaligned_fault_d.asBool,1.U(4.W),0.U(4.W)))
|
||||||
|
|
||||||
val misaligned_fault_mscause_d = WireInit(0.U(4.W))
|
|
||||||
misaligned_fault_mscause_d := Mux(regcross_misaligned_fault_d, "b0010".U, Mux(sideeffect_misaligned_fault_d.asBool, "b0001".U, "b0000".U))
|
|
||||||
|
|
||||||
|
|
||||||
io.exc_mscause_d := Mux(io.misaligned_fault_d.asBool, misaligned_fault_mscause_d(3,0), access_fault_mscause_d(3,0))
|
io.exc_mscause_d := Mux(io.misaligned_fault_d.asBool, misaligned_fault_mscause_d(3,0), access_fault_mscause_d(3,0))
|
||||||
|
io.fir_dccm_access_error_d := ((start_addr_in_dccm_region_d & ~start_addr_in_dccm_d)|(end_addr_in_dccm_region_d & ~end_addr_in_dccm_d)) & io.lsu_pkt_d.valid & io.lsu_pkt_d.fast_int
|
||||||
// Fast interrupt error logic
|
|
||||||
io.fir_dccm_access_error_d := ((start_addr_in_dccm_region_d & ~start_addr_in_dccm_d) |
|
|
||||||
(end_addr_in_dccm_region_d & ~end_addr_in_dccm_d)) & io.lsu_pkt_d.valid & io.lsu_pkt_d.fast_int
|
|
||||||
io.fir_nondccm_access_error_d := ~(start_addr_in_dccm_region_d & end_addr_in_dccm_region_d) & io.lsu_pkt_d.valid & io.lsu_pkt_d.fast_int
|
io.fir_nondccm_access_error_d := ~(start_addr_in_dccm_region_d & end_addr_in_dccm_region_d) & io.lsu_pkt_d.valid & io.lsu_pkt_d.fast_int
|
||||||
|
withClock(io.lsu_c2_m_clk){io.is_sideeffects_m := RegNext(is_sideeffects_d)} //TBD for clock and reset
|
||||||
|
|
||||||
|
|
||||||
//rvdff #(.WIDTH(1)) is_sideeffects_mff (.din(is_sideeffects_d), .dout(io.is_sideeffects_m), .clk(lsu_c2_m_clk), .*);
|
|
||||||
|
|
||||||
|
|
||||||
val is_sideeffects_mff = Module(new rvdff(1,0)) //TBD for clock and reset
|
|
||||||
is_sideeffects_mff.io.din := is_sideeffects_d
|
|
||||||
io.is_sideeffects_m := is_sideeffects_mff.io.dout
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//is_sideeffects_m :=0.U
|
|
||||||
// addr_in_dccm_d :=0.U
|
|
||||||
// addr_in_pic_d :=0.U
|
|
||||||
// addr_external_d :=0.U
|
|
||||||
// access_fault_d :=0.U
|
|
||||||
// misaligned_fault_d :=0.U
|
|
||||||
// exc_mscause_d :=0.U
|
|
||||||
// fir_dccm_access_error_d :=0.U
|
|
||||||
// fir_nondccm_access_error_d :=0.U
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//println(chisel3.Driver.emitVerilog(new el2_lsu_addrcheck))
|
//println(chisel3.Driver.emitVerilog(new el2_lsu_addrcheck))
|
||||||
|
/*
|
||||||
|
object main extends App{
|
||||||
|
println("Generate Verilog")
|
||||||
|
chisel3.Driver.execute(args, ()=> new el2_lsu_addrcheck)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
Loading…
Reference in New Issue