Bridges added
This commit is contained in:
parent
4930ba7dca
commit
59aecdc983
2
dbg.fir
2
dbg.fir
|
@ -147,7 +147,7 @@ circuit dbg :
|
||||||
module dbg :
|
module dbg :
|
||||||
input clock : Clock
|
input clock : Clock
|
||||||
input reset : AsyncReset
|
input reset : AsyncReset
|
||||||
output io : {dbg_cmd_size : UInt<2>, dbg_core_rst_l : UInt<1>, flip core_dbg_rddata : UInt<32>, flip core_dbg_cmd_done : UInt<1>, flip core_dbg_cmd_fail : UInt<1>, dbg_halt_req : UInt<1>, dbg_resume_req : UInt<1>, flip dec_tlu_debug_mode : UInt<1>, flip dec_tlu_dbg_halted : UInt<1>, flip dec_tlu_mpc_halted_only : UInt<1>, flip dec_tlu_resume_ack : UInt<1>, flip dmi_reg_en : UInt<1>, flip dmi_reg_addr : UInt<7>, flip dmi_reg_wr_en : UInt<1>, flip dmi_reg_wdata : UInt<32>, dmi_reg_rdata : UInt<32>, sb_axi : {aw : {flip ready : UInt<1>, valid : UInt<1>, bits : {id : UInt<1>, addr : UInt<32>, region : UInt<4>, len : UInt<8>, size : UInt<3>, burst : UInt<2>, lock : UInt<1>, cache : UInt<4>, prot : UInt<3>, qos : UInt<4>}}, w : {flip ready : UInt<1>, valid : UInt<1>, bits : {data : UInt<64>, strb : UInt<8>, last : UInt<1>}}, flip b : {flip ready : UInt<1>, valid : UInt<1>, bits : {resp : UInt<2>, id : UInt<1>}}, ar : {flip ready : UInt<1>, valid : UInt<1>, bits : {id : UInt<1>, addr : UInt<32>, region : UInt<4>, len : UInt<8>, size : UInt<3>, burst : UInt<2>, lock : UInt<1>, cache : UInt<4>, prot : UInt<3>, qos : UInt<4>}}, flip r : {flip ready : UInt<1>, valid : UInt<1>, bits : {id : UInt<1>, data : UInt<64>, resp : UInt<2>, last : UInt<1>}}}, flip dbg_dec : {dbg_ib : {flip dbg_cmd_valid : UInt<1>, flip dbg_cmd_write : UInt<1>, flip dbg_cmd_type : UInt<2>, flip dbg_cmd_addr : UInt<32>}, dbg_dctl : {flip dbg_cmd_wrdata : UInt<2>}}, flip dbg_dma : {dbg_ib : {flip dbg_cmd_valid : UInt<1>, flip dbg_cmd_write : UInt<1>, flip dbg_cmd_type : UInt<2>, flip dbg_cmd_addr : UInt<32>}, dbg_dctl : {flip dbg_cmd_wrdata : UInt<2>}}, flip dbg_dma_io : {flip dbg_dma_bubble : UInt<1>, dma_dbg_ready : UInt<1>}, flip dbg_bus_clk_en : UInt<1>, flip dbg_rst_l : UInt<1>, flip clk_override : UInt<1>, flip scan_mode : UInt<1>}
|
output io : {dbg_cmd_size : UInt<2>, dbg_core_rst_l : UInt<1>, flip core_dbg_rddata : UInt<32>, flip core_dbg_cmd_done : UInt<1>, flip core_dbg_cmd_fail : UInt<1>, dbg_halt_req : UInt<1>, dbg_resume_req : UInt<1>, flip dec_tlu_debug_mode : UInt<1>, flip dec_tlu_dbg_halted : UInt<1>, flip dec_tlu_mpc_halted_only : UInt<1>, flip dec_tlu_resume_ack : UInt<1>, flip dmi_reg_en : UInt<1>, flip dmi_reg_addr : UInt<7>, flip dmi_reg_wr_en : UInt<1>, flip dmi_reg_wdata : UInt<32>, dmi_reg_rdata : UInt<32>, sb_axi : {aw : {flip ready : UInt<1>, valid : UInt<1>, bits : {id : UInt<1>, addr : UInt<32>, region : UInt<4>, len : UInt<8>, size : UInt<3>, burst : UInt<2>, lock : UInt<1>, cache : UInt<4>, prot : UInt<3>, qos : UInt<4>}}, w : {flip ready : UInt<1>, valid : UInt<1>, bits : {data : UInt<64>, strb : UInt<8>, last : UInt<1>}}, flip b : {flip ready : UInt<1>, valid : UInt<1>, bits : {resp : UInt<2>, id : UInt<1>}}, ar : {flip ready : UInt<1>, valid : UInt<1>, bits : {id : UInt<1>, addr : UInt<32>, region : UInt<4>, len : UInt<8>, size : UInt<3>, burst : UInt<2>, lock : UInt<1>, cache : UInt<4>, prot : UInt<3>, qos : UInt<4>}}, flip r : {flip ready : UInt<1>, valid : UInt<1>, bits : {id : UInt<1>, data : UInt<64>, resp : UInt<2>, last : UInt<1>}}}, flip dbg_dec : {dbg_ib : {flip dbg_cmd_valid : UInt<1>, flip dbg_cmd_write : UInt<1>, flip dbg_cmd_type : UInt<2>, flip dbg_cmd_addr : UInt<32>}, dbg_dctl : {flip dbg_cmd_wrdata : UInt<32>}}, flip dbg_dma : {dbg_ib : {flip dbg_cmd_valid : UInt<1>, flip dbg_cmd_write : UInt<1>, flip dbg_cmd_type : UInt<2>, flip dbg_cmd_addr : UInt<32>}, dbg_dctl : {flip dbg_cmd_wrdata : UInt<32>}}, flip dbg_dma_io : {flip dbg_dma_bubble : UInt<1>, dma_dbg_ready : UInt<1>}, flip dbg_bus_clk_en : UInt<1>, flip dbg_rst_l : UInt<1>, flip clk_override : UInt<1>, flip scan_mode : UInt<1>}
|
||||||
|
|
||||||
wire dbg_state : UInt<3>
|
wire dbg_state : UInt<3>
|
||||||
dbg_state <= UInt<3>("h00")
|
dbg_state <= UInt<3>("h00")
|
||||||
|
|
6
dbg.v
6
dbg.v
|
@ -81,12 +81,12 @@ module dbg(
|
||||||
output io_dbg_dec_dbg_ib_dbg_cmd_write,
|
output io_dbg_dec_dbg_ib_dbg_cmd_write,
|
||||||
output [1:0] io_dbg_dec_dbg_ib_dbg_cmd_type,
|
output [1:0] io_dbg_dec_dbg_ib_dbg_cmd_type,
|
||||||
output [31:0] io_dbg_dec_dbg_ib_dbg_cmd_addr,
|
output [31:0] io_dbg_dec_dbg_ib_dbg_cmd_addr,
|
||||||
output [1:0] io_dbg_dec_dbg_dctl_dbg_cmd_wrdata,
|
output [31:0] io_dbg_dec_dbg_dctl_dbg_cmd_wrdata,
|
||||||
output io_dbg_dma_dbg_ib_dbg_cmd_valid,
|
output io_dbg_dma_dbg_ib_dbg_cmd_valid,
|
||||||
output io_dbg_dma_dbg_ib_dbg_cmd_write,
|
output io_dbg_dma_dbg_ib_dbg_cmd_write,
|
||||||
output [1:0] io_dbg_dma_dbg_ib_dbg_cmd_type,
|
output [1:0] io_dbg_dma_dbg_ib_dbg_cmd_type,
|
||||||
output [31:0] io_dbg_dma_dbg_ib_dbg_cmd_addr,
|
output [31:0] io_dbg_dma_dbg_ib_dbg_cmd_addr,
|
||||||
output [1:0] io_dbg_dma_dbg_dctl_dbg_cmd_wrdata,
|
output [31:0] io_dbg_dma_dbg_dctl_dbg_cmd_wrdata,
|
||||||
output io_dbg_dma_io_dbg_dma_bubble,
|
output io_dbg_dma_io_dbg_dma_bubble,
|
||||||
input io_dbg_dma_io_dma_dbg_ready,
|
input io_dbg_dma_io_dma_dbg_ready,
|
||||||
input io_dbg_bus_clk_en,
|
input io_dbg_bus_clk_en,
|
||||||
|
@ -678,7 +678,7 @@ module dbg(
|
||||||
assign io_dbg_dec_dbg_ib_dbg_cmd_write = command_reg[16]; // @[dbg.scala 327:35]
|
assign io_dbg_dec_dbg_ib_dbg_cmd_write = command_reg[16]; // @[dbg.scala 327:35]
|
||||||
assign io_dbg_dec_dbg_ib_dbg_cmd_type = _T_504 ? 2'h2 : _T_524; // @[dbg.scala 328:34]
|
assign io_dbg_dec_dbg_ib_dbg_cmd_type = _T_504 ? 2'h2 : _T_524; // @[dbg.scala 328:34]
|
||||||
assign io_dbg_dec_dbg_ib_dbg_cmd_addr = _T_504 ? {{1'd0}, _T_506} : _T_508; // @[dbg.scala 324:34]
|
assign io_dbg_dec_dbg_ib_dbg_cmd_addr = _T_504 ? {{1'd0}, _T_506} : _T_508; // @[dbg.scala 324:34]
|
||||||
assign io_dbg_dec_dbg_dctl_dbg_cmd_wrdata = data0_reg[1:0]; // @[dbg.scala 325:38]
|
assign io_dbg_dec_dbg_dctl_dbg_cmd_wrdata = data0_reg; // @[dbg.scala 325:38]
|
||||||
assign io_dbg_dma_dbg_ib_dbg_cmd_valid = io_dbg_dec_dbg_ib_dbg_cmd_valid; // @[dbg.scala 449:39]
|
assign io_dbg_dma_dbg_ib_dbg_cmd_valid = io_dbg_dec_dbg_ib_dbg_cmd_valid; // @[dbg.scala 449:39]
|
||||||
assign io_dbg_dma_dbg_ib_dbg_cmd_write = io_dbg_dec_dbg_ib_dbg_cmd_write; // @[dbg.scala 450:39]
|
assign io_dbg_dma_dbg_ib_dbg_cmd_write = io_dbg_dec_dbg_ib_dbg_cmd_write; // @[dbg.scala 450:39]
|
||||||
assign io_dbg_dma_dbg_ib_dbg_cmd_type = io_dbg_dec_dbg_ib_dbg_cmd_type; // @[dbg.scala 451:39]
|
assign io_dbg_dma_dbg_ib_dbg_cmd_type = io_dbg_dec_dbg_ib_dbg_cmd_type; // @[dbg.scala 451:39]
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
/home/waleedbinehsan/Desktop/Quasar/gated_latch.v
|
/home/waleedbinehsan/Desktop/Quasar/gated_latch.v
|
||||||
|
/home/waleedbinehsan/Desktop/Quasar/dmi_wrapper.sv
|
||||||
|
/home/waleedbinehsan/Desktop/Quasar/mem.sv
|
11033
quasar_wrapper.fir
11033
quasar_wrapper.fir
File diff suppressed because one or more lines are too long
6098
quasar_wrapper.v
6098
quasar_wrapper.v
File diff suppressed because it is too large
Load Diff
|
@ -450,3 +450,6 @@ class dbg extends Module with lib with RequireAsyncReset {
|
||||||
io.dbg_dma.dbg_ib.dbg_cmd_write := io.dbg_dec.dbg_ib.dbg_cmd_write
|
io.dbg_dma.dbg_ib.dbg_cmd_write := io.dbg_dec.dbg_ib.dbg_cmd_write
|
||||||
io.dbg_dma.dbg_ib.dbg_cmd_type := io.dbg_dec.dbg_ib.dbg_cmd_type
|
io.dbg_dma.dbg_ib.dbg_cmd_type := io.dbg_dec.dbg_ib.dbg_cmd_type
|
||||||
}
|
}
|
||||||
|
object dbg extends App {
|
||||||
|
println((new chisel3.stage.ChiselStage).emitVerilog(new dbg()))
|
||||||
|
}
|
|
@ -34,7 +34,7 @@ class tlu_dma extends Bundle{
|
||||||
|
|
||||||
class dec_bp extends Bundle{
|
class dec_bp extends Bundle{
|
||||||
val dec_tlu_br0_r_pkt = Flipped(Valid(new br_tlu_pkt_t))
|
val dec_tlu_br0_r_pkt = Flipped(Valid(new br_tlu_pkt_t))
|
||||||
// val dec_tlu_flush_lower_wb = Input(Bool())
|
// val dec_tlu_flush_lower_wb = Input(Bool())
|
||||||
val dec_tlu_flush_leak_one_wb = Input(Bool())
|
val dec_tlu_flush_leak_one_wb = Input(Bool())
|
||||||
val dec_tlu_bpred_disable = Input(Bool())
|
val dec_tlu_bpred_disable = Input(Bool())
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,25 @@ class dec_ifc extends Bundle{
|
||||||
val dec_tlu_mrac_ff = Input(UInt(32.W))
|
val dec_tlu_mrac_ff = Input(UInt(32.W))
|
||||||
val ifu_pmu_fetch_stall = Output(Bool())
|
val ifu_pmu_fetch_stall = Output(Bool())
|
||||||
}
|
}
|
||||||
|
class ahb_in extends Bundle{
|
||||||
|
val hrdata = Input(UInt(64.W)) // [63:0] // ahb bus read data
|
||||||
|
val hready = Input(Bool()) // slave ready to accept transaction
|
||||||
|
val hresp = Input(Bool()) // slave response (high indicates erro)
|
||||||
|
}
|
||||||
|
class ahb_out extends Bundle{
|
||||||
|
val haddr = Output(UInt(32.W)) // [31:0] // ahb bus address
|
||||||
|
val hburst = Output(UInt(3.W)) // [2:0] // tied to 0
|
||||||
|
val hmastlock = Output(Bool()) // tied to 0
|
||||||
|
val hprot = Output(UInt(4.W)) // [3:0] // tied to 4'b0011
|
||||||
|
val hsize = Output(UInt(3.W)) // [2:0] // size of bus transaction (possible values 0,1,2,3)
|
||||||
|
val htrans = Output(UInt(2.W))
|
||||||
|
val hwrite = Output(Bool()) // ahb bus write
|
||||||
|
val hwdata = Output(UInt(64.W)) // [63:0] // ahb bus write data
|
||||||
|
}
|
||||||
|
class ahb_channel extends Bundle{
|
||||||
|
val in = Input(new ahb_in)
|
||||||
|
val out = Output(new ahb_out)
|
||||||
|
}
|
||||||
class axi_channels(val BUS_TAG :Int=3) extends Bundle with lib{
|
class axi_channels(val BUS_TAG :Int=3) extends Bundle with lib{
|
||||||
val aw = Decoupled(new write_addr(BUS_TAG))
|
val aw = Decoupled(new write_addr(BUS_TAG))
|
||||||
val w = Decoupled(new write_data())
|
val w = Decoupled(new write_data())
|
||||||
|
@ -92,7 +111,7 @@ class write_resp(val TAG : Int=3) extends Bundle with lib{ // write_response
|
||||||
}
|
}
|
||||||
|
|
||||||
class dec_mem_ctrl extends Bundle with lib{
|
class dec_mem_ctrl extends Bundle with lib{
|
||||||
// val dec_tlu_flush_lower_wb = Input(Bool())
|
// val dec_tlu_flush_lower_wb = Input(Bool())
|
||||||
val dec_tlu_flush_err_wb = Input(Bool())
|
val dec_tlu_flush_err_wb = Input(Bool())
|
||||||
val dec_tlu_i0_commit_cmt = Input(Bool())
|
val dec_tlu_i0_commit_cmt = Input(Bool())
|
||||||
val dec_tlu_force_halt = Input(Bool())
|
val dec_tlu_force_halt = Input(Bool())
|
||||||
|
@ -288,7 +307,7 @@ class dbg_ib extends Bundle{
|
||||||
}
|
}
|
||||||
|
|
||||||
class dbg_dctl extends Bundle{
|
class dbg_dctl extends Bundle{
|
||||||
val dbg_cmd_wrdata = Input(UInt(2.W)) // command write data, for fence/fence_i
|
val dbg_cmd_wrdata = Input(UInt(32.W)) // command write data, for fence/fence_i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -514,7 +533,7 @@ class lsu_pkt_t extends Bundle {
|
||||||
val store_data_bypass_d = Bool()
|
val store_data_bypass_d = Bool()
|
||||||
val load_ldst_bypass_d = Bool()
|
val load_ldst_bypass_d = Bool()
|
||||||
val store_data_bypass_m = Bool()
|
val store_data_bypass_m = Bool()
|
||||||
// val valid = Bool()
|
// val valid = Bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
class lsu_error_pkt_t extends Bundle {
|
class lsu_error_pkt_t extends Bundle {
|
||||||
|
|
|
@ -20,14 +20,14 @@ class ahb_to_axi4 extends Module with lib with RequireAsyncReset {
|
||||||
val axi_rid = Input(UInt(TAG.W))
|
val axi_rid = Input(UInt(TAG.W))
|
||||||
val axi_rdata = Input(UInt(64.W))
|
val axi_rdata = Input(UInt(64.W))
|
||||||
val axi_rresp = Input(UInt(2.W))
|
val axi_rresp = Input(UInt(2.W))
|
||||||
val ahb_haddr = Input(UInt(32.W)) // ahb bus address
|
// val ahb_haddr = Input(UInt(32.W)) // ahb bus address
|
||||||
val ahb_hburst = Input(UInt(3.W)) // tied to 0
|
// val ahb_hburst = Input(UInt(3.W)) // tied to 0
|
||||||
val ahb_hmastlock = Input(Bool()) // tied to 0
|
// val ahb_hmastlock = Input(Bool()) // tied to 0
|
||||||
val ahb_hprot = Input(UInt(4.W)) // tied to 4'b0011
|
// val ahb_hprot = Input(UInt(4.W)) // tied to 4'b0011
|
||||||
val ahb_hsize = Input(UInt(3.W)) // size of bus transaction (possible values 0 =1 =2 =3)
|
// val ahb_hsize = Input(UInt(3.W)) // size of bus transaction (possible values 0 =1 =2 =3)
|
||||||
val ahb_htrans = Input(UInt(2.W)) // Transaction type (possible values 0 =2 only right now)
|
// val ahb_htrans = Input(UInt(2.W)) // Transaction type (possible values 0 =2 only right now)
|
||||||
val ahb_hwrite = Input(Bool()) // ahb bus write
|
// val ahb_hwrite = Input(Bool()) // ahb bus write
|
||||||
val ahb_hwdata = Input(UInt(64.W)) // ahb bus write data
|
// val ahb_hwdata = Input(UInt(64.W)) // ahb bus write data
|
||||||
val ahb_hsel = Input(Bool()) // this slave was selected
|
val ahb_hsel = Input(Bool()) // this slave was selected
|
||||||
val ahb_hreadyin = Input(Bool()) // previous hready was accepted or not
|
val ahb_hreadyin = Input(Bool()) // previous hready was accepted or not
|
||||||
// outputs
|
// outputs
|
||||||
|
@ -51,9 +51,10 @@ class ahb_to_axi4 extends Module with lib with RequireAsyncReset {
|
||||||
val axi_arlen = Output(UInt(8.W))
|
val axi_arlen = Output(UInt(8.W))
|
||||||
val axi_arburst = Output(UInt(2.W))
|
val axi_arburst = Output(UInt(2.W))
|
||||||
val axi_rready = Output(Bool())
|
val axi_rready = Output(Bool())
|
||||||
val ahb_hrdata = Output(UInt(64.W)) // ahb bus read data
|
val ahb = Flipped(new ahb_channel())
|
||||||
val ahb_hreadyout = Output(Bool()) // slave ready to accept transaction
|
// val ahb_hrdata = Output(UInt(64.W)) // ahb bus read data
|
||||||
val ahb_hresp = Output(Bool()) // slave response (high indicates erro)
|
// val ahb_hreadyout = Output(Bool()) // slave ready to accept transaction
|
||||||
|
// val ahb_hresp = Output(Bool()) // slave response (high indicates erro)
|
||||||
})
|
})
|
||||||
val idle:: wr :: rd :: pend :: Nil = Enum(4)
|
val idle:: wr :: rd :: pend :: Nil = Enum(4)
|
||||||
val TAG= 1
|
val TAG= 1
|
||||||
|
@ -114,18 +115,18 @@ class ahb_to_axi4 extends Module with lib with RequireAsyncReset {
|
||||||
switch(buf_state) {
|
switch(buf_state) {
|
||||||
|
|
||||||
is(idle) {
|
is(idle) {
|
||||||
buf_nxtstate := Mux(io.ahb_hwrite, wr, rd)
|
buf_nxtstate := Mux(io.ahb.out.hwrite, wr, rd)
|
||||||
buf_state_en := ahb_hready & io.ahb_htrans(1) & io.ahb_hsel // only transition on a valid hrtans
|
buf_state_en := ahb_hready & io.ahb.out.htrans(1) & io.ahb_hsel // only transition on a valid hrtans
|
||||||
}
|
}
|
||||||
is(wr) { // Write command recieved last cycle
|
is(wr) { // Write command recieved last cycle
|
||||||
buf_nxtstate := Mux((io.ahb_hresp | (io.ahb_htrans(1, 0) === "b0".U) | !io.ahb_hsel).asBool, idle, Mux(io.ahb_hwrite, wr, rd))
|
buf_nxtstate := Mux((io.ahb.in.hresp | (io.ahb.out.htrans(1, 0) === "b0".U) | !io.ahb_hsel).asBool, idle, Mux(io.ahb.out.hwrite, wr, rd))
|
||||||
buf_state_en := (!cmdbuf_full | io.ahb_hresp)
|
buf_state_en := (!cmdbuf_full | io.ahb.in.hresp)
|
||||||
cmdbuf_wr_en := !cmdbuf_full & !(io.ahb_hresp | ((io.ahb_htrans(1, 0) === "b01".U(2.W)) & io.ahb_hsel)) // Dont send command to the buffer in case of an error or when the master is not ready with the data now.
|
cmdbuf_wr_en := !cmdbuf_full & !(io.ahb.in.hresp | ((io.ahb.out.htrans(1, 0) === "b01".U(2.W)) & io.ahb_hsel)) // Dont send command to the buffer in case of an error or when the master is not ready with the data now.
|
||||||
}
|
}
|
||||||
is(rd) { // Read command recieved last cycle.
|
is(rd) { // Read command recieved last cycle.
|
||||||
buf_nxtstate := Mux(io.ahb_hresp, idle, pend) // If error go to idle, else wait for read data
|
buf_nxtstate := Mux(io.ahb.in.hresp, idle, pend) // If error go to idle, else wait for read data
|
||||||
buf_state_en := (!cmdbuf_full | io.ahb_hresp) // only when command can go, or if its an error
|
buf_state_en := (!cmdbuf_full | io.ahb.in.hresp) // only when command can go, or if its an error
|
||||||
cmdbuf_wr_en := !io.ahb_hresp & !cmdbuf_full // send command only when no error
|
cmdbuf_wr_en := !io.ahb.in.hresp & !cmdbuf_full // send command only when no error
|
||||||
}
|
}
|
||||||
is(pend) { // Read Command has been sent. Waiting on Data.
|
is(pend) { // Read Command has been sent. Waiting on Data.
|
||||||
buf_nxtstate := idle // go back for next command and present data next cycle
|
buf_nxtstate := idle // go back for next command and present data next cycle
|
||||||
|
@ -142,11 +143,11 @@ class ahb_to_axi4 extends Module with lib with RequireAsyncReset {
|
||||||
(Fill(8,ahb_hsize_q(2,0) === 3.U) & 255.U)
|
(Fill(8,ahb_hsize_q(2,0) === 3.U) & 255.U)
|
||||||
|
|
||||||
// AHB signals
|
// AHB signals
|
||||||
io.ahb_hreadyout := Mux(io.ahb_hresp,(ahb_hresp_q & !ahb_hready_q), ((!cmdbuf_full | (buf_state === idle)) & !(buf_state === rd | buf_state === pend) & !buf_read_error))
|
io.ahb.in.hready := Mux(io.ahb.in.hresp,(ahb_hresp_q & !ahb_hready_q), ((!cmdbuf_full | (buf_state === idle)) & !(buf_state === rd | buf_state === pend) & !buf_read_error))
|
||||||
ahb_hready := io.ahb_hreadyout & io.ahb_hreadyin
|
ahb_hready := io.ahb.in.hready & io.ahb_hreadyin
|
||||||
ahb_htrans_in := Fill(2,io.ahb_hsel) & io.ahb_htrans(1,0)
|
ahb_htrans_in := Fill(2,io.ahb_hsel) & io.ahb.out.htrans(1,0)
|
||||||
io.ahb_hrdata := buf_rdata(63,0)
|
io.ahb.in.hrdata := buf_rdata(63,0)
|
||||||
io.ahb_hresp := ((ahb_htrans_q(1,0) =/= 0.U) & (buf_state =/= idle) &
|
io.ahb.in.hresp := ((ahb_htrans_q(1,0) =/= 0.U) & (buf_state =/= idle) &
|
||||||
((!(ahb_addr_in_dccm | ahb_addr_in_iccm)) | // request not for ICCM or DCCM
|
((!(ahb_addr_in_dccm | ahb_addr_in_iccm)) | // request not for ICCM or DCCM
|
||||||
((ahb_addr_in_iccm | (ahb_addr_in_dccm & ahb_hwrite_q)) & !((ahb_hsize_q(1,0) === 2.U) | (ahb_hsize_q(1,0) === 3.U))) | // ICCM Rd/Wr OR DCCM Wr not the right size
|
((ahb_addr_in_iccm | (ahb_addr_in_dccm & ahb_hwrite_q)) & !((ahb_hsize_q(1,0) === 2.U) | (ahb_hsize_q(1,0) === 3.U))) | // ICCM Rd/Wr OR DCCM Wr not the right size
|
||||||
((ahb_hsize_q(2,0) === 1.U) & ahb_haddr_q(0)) | // HW size but unaligned
|
((ahb_hsize_q(2,0) === 1.U) & ahb_haddr_q(0)) | // HW size but unaligned
|
||||||
|
@ -160,22 +161,22 @@ class ahb_to_axi4 extends Module with lib with RequireAsyncReset {
|
||||||
buf_read_error := withClock(ahb_clk){RegNext(buf_read_error_in,0.U)}
|
buf_read_error := withClock(ahb_clk){RegNext(buf_read_error_in,0.U)}
|
||||||
|
|
||||||
// All the Master signals are captured before presenting it to the command buffer. We check for Hresp before sending it to the cmd buffer.
|
// All the Master signals are captured before presenting it to the command buffer. We check for Hresp before sending it to the cmd buffer.
|
||||||
ahb_hresp_q := withClock(ahb_clk){RegNext(io.ahb_hresp,0.U)}
|
ahb_hresp_q := withClock(ahb_clk){RegNext(io.ahb.in.hresp,0.U)}
|
||||||
ahb_hready_q := withClock(ahb_clk){RegNext(ahb_hready,0.U)}
|
ahb_hready_q := withClock(ahb_clk){RegNext(ahb_hready,0.U)}
|
||||||
ahb_htrans_q := withClock(ahb_clk){RegNext(ahb_htrans_in,0.U)}
|
ahb_htrans_q := withClock(ahb_clk){RegNext(ahb_htrans_in,0.U)}
|
||||||
ahb_hsize_q := withClock(ahb_addr_clk){RegNext(io.ahb_hsize,0.U)}
|
ahb_hsize_q := withClock(ahb_addr_clk){RegNext(io.ahb.out.hsize,0.U)}
|
||||||
ahb_hwrite_q := withClock(ahb_addr_clk){RegNext(io.ahb_hwrite,0.U)}
|
ahb_hwrite_q := withClock(ahb_addr_clk){RegNext(io.ahb.out.hwrite,0.U)}
|
||||||
ahb_haddr_q := withClock(ahb_addr_clk){RegNext(io.ahb_haddr,0.U)}
|
ahb_haddr_q := withClock(ahb_addr_clk){RegNext(io.ahb.out.haddr,0.U)}
|
||||||
|
|
||||||
// Clock header logic
|
// Clock header logic
|
||||||
ahb_bus_addr_clk_en := io.bus_clk_en & (ahb_hready & io.ahb_htrans(1))
|
ahb_bus_addr_clk_en := io.bus_clk_en & (ahb_hready & io.ahb.out.htrans(1))
|
||||||
buf_rdata_clk_en := io.bus_clk_en & buf_rdata_en;
|
buf_rdata_clk_en := io.bus_clk_en & buf_rdata_en;
|
||||||
|
|
||||||
ahb_clk := rvclkhdr(clock, io.bus_clk_en, io.scan_mode)
|
ahb_clk := rvclkhdr(clock, io.bus_clk_en, io.scan_mode)
|
||||||
ahb_addr_clk := rvclkhdr(clock, ahb_bus_addr_clk_en, io.scan_mode)
|
ahb_addr_clk := rvclkhdr(clock, ahb_bus_addr_clk_en, io.scan_mode)
|
||||||
buf_rdata_clk := rvclkhdr(clock, buf_rdata_clk_en, io.scan_mode)
|
buf_rdata_clk := rvclkhdr(clock, buf_rdata_clk_en, io.scan_mode)
|
||||||
|
|
||||||
cmdbuf_rst := (((io.axi_awvalid & io.axi_awready) | (io.axi_arvalid & io.axi_arready)) & !cmdbuf_wr_en) | (io.ahb_hresp & !cmdbuf_write)
|
cmdbuf_rst := (((io.axi_awvalid & io.axi_awready) | (io.axi_arvalid & io.axi_arready)) & !cmdbuf_wr_en) | (io.ahb.in.hresp & !cmdbuf_write)
|
||||||
cmdbuf_full := (cmdbuf_vld & !((io.axi_awvalid & io.axi_awready) | (io.axi_arvalid & io.axi_arready)))
|
cmdbuf_full := (cmdbuf_vld & !((io.axi_awvalid & io.axi_awready) | (io.axi_arvalid & io.axi_arready)))
|
||||||
//rvdffsc
|
//rvdffsc
|
||||||
cmdbuf_vld := withClock(bus_clk) {RegNext((Mux(cmdbuf_wr_en.asBool(),"b1".U,cmdbuf_vld) & !cmdbuf_rst), 0.U)}
|
cmdbuf_vld := withClock(bus_clk) {RegNext((Mux(cmdbuf_wr_en.asBool(),"b1".U,cmdbuf_vld) & !cmdbuf_rst), 0.U)}
|
||||||
|
@ -192,7 +193,7 @@ class ahb_to_axi4 extends Module with lib with RequireAsyncReset {
|
||||||
|
|
||||||
//rvdffe
|
//rvdffe
|
||||||
cmdbuf_addr := rvdffe(ahb_haddr_q, cmdbuf_wr_en.asBool(),bus_clk,io.scan_mode)
|
cmdbuf_addr := rvdffe(ahb_haddr_q, cmdbuf_wr_en.asBool(),bus_clk,io.scan_mode)
|
||||||
cmdbuf_wdata := rvdffe(io.ahb_hwdata, cmdbuf_wr_en.asBool(),bus_clk,io.scan_mode)
|
cmdbuf_wdata := rvdffe(io.ahb.out.hwdata, cmdbuf_wr_en.asBool(),bus_clk,io.scan_mode)
|
||||||
|
|
||||||
// AXI Write Command Channel
|
// AXI Write Command Channel
|
||||||
io.axi_awvalid := cmdbuf_vld & cmdbuf_write
|
io.axi_awvalid := cmdbuf_vld & cmdbuf_write
|
||||||
|
@ -223,3 +224,6 @@ class ahb_to_axi4 extends Module with lib with RequireAsyncReset {
|
||||||
|
|
||||||
bus_clk := rvclkhdr(clock, io.bus_clk_en, io.scan_mode)
|
bus_clk := rvclkhdr(clock, io.bus_clk_en, io.scan_mode)
|
||||||
}
|
}
|
||||||
|
object AHB_main extends App {
|
||||||
|
println("Generate Verilog")
|
||||||
|
println((new chisel3.stage.ChiselStage).emitVerilog(new ahb_to_axi4()))}
|
|
@ -2,6 +2,7 @@ package lib
|
||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
|
import include._
|
||||||
|
|
||||||
trait Config {
|
trait Config {
|
||||||
val TAG = 1
|
val TAG = 1
|
||||||
|
@ -28,9 +29,6 @@ class axi4_to_ahb_IO extends Bundle with Config {
|
||||||
val axi_arsize = Input(UInt(3.W)) // [2:0]
|
val axi_arsize = Input(UInt(3.W)) // [2:0]
|
||||||
val axi_arprot = Input(UInt(3.W)) // [2:0]
|
val axi_arprot = Input(UInt(3.W)) // [2:0]
|
||||||
val axi_rready = Input(Bool())
|
val axi_rready = Input(Bool())
|
||||||
val ahb_hrdata = Input(UInt(64.W)) // [63:0] // ahb bus read data
|
|
||||||
val ahb_hready = Input(Bool()) // slave ready to accept transaction
|
|
||||||
val ahb_hresp = Input(Bool()) // slave response (high indicates erro)
|
|
||||||
//----------------------------outputs---------------------------
|
//----------------------------outputs---------------------------
|
||||||
val axi_awready = Output(Bool())
|
val axi_awready = Output(Bool())
|
||||||
val axi_wready = Output(Bool())
|
val axi_wready = Output(Bool())
|
||||||
|
@ -45,16 +43,12 @@ class axi4_to_ahb_IO extends Bundle with Config {
|
||||||
val axi_rresp = Output(UInt(2.W)) // 1:0]
|
val axi_rresp = Output(UInt(2.W)) // 1:0]
|
||||||
val axi_rlast = Output(Bool())
|
val axi_rlast = Output(Bool())
|
||||||
// AHB-Lite signals
|
// AHB-Lite signals
|
||||||
val ahb_haddr = Output(UInt(32.W)) // [31:0] // ahb bus address
|
val ahb = new ahb_channel
|
||||||
val ahb_hburst = Output(UInt(3.W)) // [2:0] // tied to 0
|
|
||||||
val ahb_hmastlock = Output(Bool()) // tied to 0
|
|
||||||
val ahb_hprot = Output(UInt(4.W)) // [3:0] // tied to 4'b0011
|
|
||||||
val ahb_hsize = Output(UInt(3.W)) // [2:0] // size of bus transaction (possible values 0,1,2,3)
|
|
||||||
val ahb_htrans = Output(UInt(2.W))
|
|
||||||
val ahb_hwrite = Output(Bool()) // ahb bus write
|
|
||||||
val ahb_hwdata = Output(UInt(64.W)) // [63:0] // ahb bus write data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class axi4_to_ahb extends Module with lib with RequireAsyncReset with Config {
|
class axi4_to_ahb extends Module with lib with RequireAsyncReset with Config {
|
||||||
val io = IO(new axi4_to_ahb_IO)
|
val io = IO(new axi4_to_ahb_IO)
|
||||||
val buf_rst = WireInit(0.U(1.W))
|
val buf_rst = WireInit(0.U(1.W))
|
||||||
|
@ -202,7 +196,7 @@ class axi4_to_ahb extends Module with lib with RequireAsyncReset with Config {
|
||||||
bus_write_clk := rvclkhdr(clock, bus_write_clk_en.asBool(), io.scan_mode)
|
bus_write_clk := rvclkhdr(clock, bus_write_clk_en.asBool(), io.scan_mode)
|
||||||
|
|
||||||
//State machine
|
//State machine
|
||||||
io.ahb_htrans := 0.U
|
io.ahb.out.htrans := 0.U
|
||||||
master_ready := 0.U
|
master_ready := 0.U
|
||||||
buf_state_en := false.B
|
buf_state_en := false.B
|
||||||
buf_nxtstate := idle
|
buf_nxtstate := idle
|
||||||
|
@ -233,7 +227,7 @@ class axi4_to_ahb extends Module with lib with RequireAsyncReset with Config {
|
||||||
buf_cmd_byte_ptr := Mux(buf_write_in.asBool(), (get_nxtbyte_ptr(0.U(3.W), buf_byteen_in(7, 0), false.B)), master_addr(2, 0))
|
buf_cmd_byte_ptr := Mux(buf_write_in.asBool(), (get_nxtbyte_ptr(0.U(3.W), buf_byteen_in(7, 0), false.B)), master_addr(2, 0))
|
||||||
bypass_en := buf_state_en
|
bypass_en := buf_state_en
|
||||||
rd_bypass_idle := bypass_en & (buf_nxtstate === cmd_rd)
|
rd_bypass_idle := bypass_en & (buf_nxtstate === cmd_rd)
|
||||||
io.ahb_htrans := (Fill(2, bypass_en)) & "b10".U
|
io.ahb.out.htrans := (Fill(2, bypass_en)) & "b10".U
|
||||||
}
|
}
|
||||||
|
|
||||||
is(cmd_rd) {
|
is(cmd_rd) {
|
||||||
|
@ -245,7 +239,7 @@ class axi4_to_ahb extends Module with lib with RequireAsyncReset with Config {
|
||||||
buf_wr_en := master_ready
|
buf_wr_en := master_ready
|
||||||
bypass_en := master_ready & master_valid
|
bypass_en := master_ready & master_valid
|
||||||
buf_cmd_byte_ptr := Mux(bypass_en.asBool(), master_addr(2, 0), buf_addr(2, 0))
|
buf_cmd_byte_ptr := Mux(bypass_en.asBool(), master_addr(2, 0), buf_addr(2, 0))
|
||||||
io.ahb_htrans := "b10".U & (Fill(2, (!buf_state_en | bypass_en)))
|
io.ahb.out.htrans := "b10".U & (Fill(2, (!buf_state_en | bypass_en)))
|
||||||
}
|
}
|
||||||
|
|
||||||
is(stream_rd) {
|
is(stream_rd) {
|
||||||
|
@ -260,7 +254,7 @@ class axi4_to_ahb extends Module with lib with RequireAsyncReset with Config {
|
||||||
cmd_done := buf_state_en & !master_valid // last one of the stream should not send a htrans
|
cmd_done := buf_state_en & !master_valid // last one of the stream should not send a htrans
|
||||||
bypass_en := master_ready & master_valid & (buf_nxtstate === stream_rd) & buf_state_en
|
bypass_en := master_ready & master_valid & (buf_nxtstate === stream_rd) & buf_state_en
|
||||||
buf_cmd_byte_ptr := Mux(bypass_en.asBool(), master_addr(2, 0), buf_addr(2, 0))
|
buf_cmd_byte_ptr := Mux(bypass_en.asBool(), master_addr(2, 0), buf_addr(2, 0))
|
||||||
io.ahb_htrans := "b10".U & Fill(2, (!((buf_nxtstate =/= stream_rd) & buf_state_en)))
|
io.ahb.out.htrans := "b10".U & Fill(2, (!((buf_nxtstate =/= stream_rd) & buf_state_en)))
|
||||||
slvbuf_wr_en := buf_wr_en// shifting the contents from the buf to slv_buf for streaming cases
|
slvbuf_wr_en := buf_wr_en// shifting the contents from the buf to slv_buf for streaming cases
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +264,7 @@ class axi4_to_ahb extends Module with lib with RequireAsyncReset with Config {
|
||||||
slave_valid_pre := buf_state_en
|
slave_valid_pre := buf_state_en
|
||||||
slvbuf_wr_en := buf_state_en // Overwrite slvbuf with buffer
|
slvbuf_wr_en := buf_state_en // Overwrite slvbuf with buffer
|
||||||
buf_cmd_byte_ptr := buf_addr(2, 0)
|
buf_cmd_byte_ptr := buf_addr(2, 0)
|
||||||
io.ahb_htrans := "b10".U(2.W) & Fill(2, !buf_state_en)
|
io.ahb.out.htrans := "b10".U(2.W) & Fill(2, !buf_state_en)
|
||||||
}
|
}
|
||||||
|
|
||||||
is(data_rd) {
|
is(data_rd) {
|
||||||
|
@ -290,7 +284,7 @@ class axi4_to_ahb extends Module with lib with RequireAsyncReset with Config {
|
||||||
slvbuf_wr_en := buf_state_en
|
slvbuf_wr_en := buf_state_en
|
||||||
buf_cmd_byte_ptr := Mux(trxn_done.asBool(), (get_nxtbyte_ptr(buf_cmd_byte_ptrQ(2, 0), buf_byteen(7, 0), true.B)), buf_cmd_byte_ptrQ)
|
buf_cmd_byte_ptr := Mux(trxn_done.asBool(), (get_nxtbyte_ptr(buf_cmd_byte_ptrQ(2, 0), buf_byteen(7, 0), true.B)), buf_cmd_byte_ptrQ)
|
||||||
cmd_done := trxn_done & (buf_aligned | (buf_cmd_byte_ptrQ === "b111".U) | (buf_byteen((get_nxtbyte_ptr(buf_cmd_byte_ptrQ(2, 0), buf_byteen(7, 0), true.B))) === "b0".U))
|
cmd_done := trxn_done & (buf_aligned | (buf_cmd_byte_ptrQ === "b111".U) | (buf_byteen((get_nxtbyte_ptr(buf_cmd_byte_ptrQ(2, 0), buf_byteen(7, 0), true.B))) === "b0".U))
|
||||||
io.ahb_htrans := Fill(2, !(cmd_done | cmd_doneQ)) & "b10".U
|
io.ahb.out.htrans := Fill(2, !(cmd_done | cmd_doneQ)) & "b10".U
|
||||||
}
|
}
|
||||||
|
|
||||||
is(data_wr) {
|
is(data_wr) {
|
||||||
|
@ -305,7 +299,7 @@ class axi4_to_ahb extends Module with lib with RequireAsyncReset with Config {
|
||||||
cmd_done := (ahb_hresp_q | (ahb_hready_q & (ahb_htrans_q(1,0) =/= 0.U) &
|
cmd_done := (ahb_hresp_q | (ahb_hready_q & (ahb_htrans_q(1,0) =/= 0.U) &
|
||||||
((buf_cmd_byte_ptrQ === 7.U) | (buf_byteen(get_nxtbyte_ptr(buf_cmd_byte_ptrQ(2,0),buf_byteen(7,0),true.B)) === 0.U))))
|
((buf_cmd_byte_ptrQ === 7.U) | (buf_byteen(get_nxtbyte_ptr(buf_cmd_byte_ptrQ(2,0),buf_byteen(7,0),true.B)) === 0.U))))
|
||||||
bypass_en := buf_state_en & buf_write_in & (buf_nxtstate === cmd_wr)
|
bypass_en := buf_state_en & buf_write_in & (buf_nxtstate === cmd_wr)
|
||||||
io.ahb_htrans := Fill(2, (!(cmd_done | cmd_doneQ) | bypass_en)) & 2.U
|
io.ahb.out.htrans := Fill(2, (!(cmd_done | cmd_doneQ) | bypass_en)) & 2.U
|
||||||
slave_valid_pre := buf_state_en & (buf_nxtstate =/= done)
|
slave_valid_pre := buf_state_en & (buf_nxtstate =/= done)
|
||||||
trxn_done := ahb_hready_q & ahb_hwrite_q & (ahb_htrans_q(1,0) =/= 0.U)
|
trxn_done := ahb_hready_q & ahb_hwrite_q & (ahb_htrans_q(1,0) =/= 0.U)
|
||||||
buf_cmd_byte_ptr_en := trxn_done | bypass_en
|
buf_cmd_byte_ptr_en := trxn_done | bypass_en
|
||||||
|
@ -349,21 +343,21 @@ class axi4_to_ahb extends Module with lib with RequireAsyncReset with Config {
|
||||||
((master_size(1, 0) === "b11".U) & ((master_byteen(7, 0) === "h3".U) | (master_byteen(7, 0) === "hc".U) | (master_byteen(7, 0) === "h30".U) | (master_byteen(7, 0) === "hc0".U) |
|
((master_size(1, 0) === "b11".U) & ((master_byteen(7, 0) === "h3".U) | (master_byteen(7, 0) === "hc".U) | (master_byteen(7, 0) === "h30".U) | (master_byteen(7, 0) === "hc0".U) |
|
||||||
(master_byteen(7, 0) === "hf".U) | (master_byteen(7, 0) === "hf0".U) | (master_byteen(7, 0) === "hff".U)))
|
(master_byteen(7, 0) === "hf".U) | (master_byteen(7, 0) === "hf0".U) | (master_byteen(7, 0) === "hff".U)))
|
||||||
// Generate the ahb signals
|
// Generate the ahb signals
|
||||||
io.ahb_haddr := Mux(bypass_en.asBool(), Cat(master_addr(31, 3), buf_cmd_byte_ptr(2, 0)), Cat(buf_addr(31, 3), buf_cmd_byte_ptr(2, 0)))
|
io.ahb.out.haddr := Mux(bypass_en.asBool(), Cat(master_addr(31, 3), buf_cmd_byte_ptr(2, 0)), Cat(buf_addr(31, 3), buf_cmd_byte_ptr(2, 0)))
|
||||||
io.ahb_hsize := Mux(bypass_en.asBool(), Cat(0.U, (Fill(2, buf_aligned_in) & buf_size_in(1, 0))), Cat("b0".U, (Fill(2, buf_aligned) & buf_size(1, 0))))
|
io.ahb.out.hsize := Mux(bypass_en.asBool(), Cat(0.U, (Fill(2, buf_aligned_in) & buf_size_in(1, 0))), Cat("b0".U, (Fill(2, buf_aligned) & buf_size(1, 0))))
|
||||||
|
|
||||||
io.ahb_hburst := "b0".U
|
io.ahb.out.hburst := "b0".U
|
||||||
io.ahb_hmastlock := "b0".U
|
io.ahb.out.hmastlock := "b0".U
|
||||||
io.ahb_hprot := Cat("b001".U, ~io.axi_arprot(2))
|
io.ahb.out.hprot := Cat("b001".U, ~io.axi_arprot(2))
|
||||||
io.ahb_hwrite := Mux(bypass_en.asBool(), (master_opc(2, 1) === "b01".U), buf_write)
|
io.ahb.out.hwrite := Mux(bypass_en.asBool(), (master_opc(2, 1) === "b01".U), buf_write)
|
||||||
io.ahb_hwdata := buf_data(63, 0)
|
io.ahb.out.hwdata := buf_data(63, 0)
|
||||||
|
|
||||||
slave_valid := slave_valid_pre
|
slave_valid := slave_valid_pre
|
||||||
slave_opc := Cat(Mux(slvbuf_write.asBool(), "b11".U, "b00".U), Fill(2, slvbuf_error) & "b10".U)
|
slave_opc := Cat(Mux(slvbuf_write.asBool(), "b11".U, "b00".U), Fill(2, slvbuf_error) & "b10".U)
|
||||||
slave_rdata := Mux(slvbuf_error.asBool(), Fill(2, last_bus_addr(31, 0)), Mux((buf_state === done), buf_data(63, 0), ahb_hrdata_q(63, 0)))
|
slave_rdata := Mux(slvbuf_error.asBool(), Fill(2, last_bus_addr(31, 0)), Mux((buf_state === done), buf_data(63, 0), ahb_hrdata_q(63, 0)))
|
||||||
slave_tag := slvbuf_tag(TAG - 1, 0)
|
slave_tag := slvbuf_tag(TAG - 1, 0)
|
||||||
|
|
||||||
last_addr_en := (io.ahb_htrans(1, 0) =/= "b0".U) & io.ahb_hready & io.ahb_hwrite
|
last_addr_en := (io.ahb.out.htrans(1, 0) =/= "b0".U) & io.ahb.in.hready & io.ahb.out.hwrite
|
||||||
// Write buffer
|
// Write buffer
|
||||||
wrbuf_en := io.axi_awvalid & io.axi_awready & master_ready
|
wrbuf_en := io.axi_awvalid & io.axi_awready & master_ready
|
||||||
wrbuf_data_en := io.axi_wvalid & io.axi_wready & master_ready
|
wrbuf_data_en := io.axi_wvalid & io.axi_wready & master_ready
|
||||||
|
@ -382,7 +376,7 @@ class axi4_to_ahb extends Module with lib with RequireAsyncReset with Config {
|
||||||
wrbuf_addr := rvdffe(io.axi_awaddr, wrbuf_en.asBool,bus_clk,io.scan_mode)
|
wrbuf_addr := rvdffe(io.axi_awaddr, wrbuf_en.asBool,bus_clk,io.scan_mode)
|
||||||
wrbuf_data := rvdffe(io.axi_wdata, wrbuf_data_en.asBool,bus_clk,io.scan_mode)
|
wrbuf_data := rvdffe(io.axi_wdata, wrbuf_data_en.asBool,bus_clk,io.scan_mode)
|
||||||
wrbuf_byteen := withClock(bus_clk) {RegEnable(io.axi_wstrb(7, 0), 0.U, wrbuf_data_en.asBool())}
|
wrbuf_byteen := withClock(bus_clk) {RegEnable(io.axi_wstrb(7, 0), 0.U, wrbuf_data_en.asBool())}
|
||||||
last_bus_addr := withClock(ahbm_clk) {RegEnable(io.ahb_haddr(31, 0), 0.U, last_addr_en.asBool())}
|
last_bus_addr := withClock(ahbm_clk) {RegEnable(io.ahb.out.haddr(31, 0), 0.U, last_addr_en.asBool())}
|
||||||
buf_write := withClock(buf_clk) {RegEnable(buf_write_in, 0.U, buf_wr_en.asBool())}
|
buf_write := withClock(buf_clk) {RegEnable(buf_write_in, 0.U, buf_wr_en.asBool())}
|
||||||
buf_tag := withClock(buf_clk) {RegEnable(buf_tag_in(TAG - 1, 0), 0.U, buf_wr_en.asBool())}
|
buf_tag := withClock(buf_clk) {RegEnable(buf_tag_in(TAG - 1, 0), 0.U, buf_wr_en.asBool())}
|
||||||
buf_addr := rvdffe(buf_addr_in(31, 0),(buf_wr_en & io.bus_clk_en).asBool,clock,io.scan_mode)
|
buf_addr := rvdffe(buf_addr_in(31, 0),(buf_wr_en & io.bus_clk_en).asBool,clock,io.scan_mode)
|
||||||
|
@ -395,14 +389,14 @@ class axi4_to_ahb extends Module with lib with RequireAsyncReset with Config {
|
||||||
slvbuf_error := withClock(ahbm_clk) {RegEnable(slvbuf_error_in, 0.U, slvbuf_error_en.asBool())}
|
slvbuf_error := withClock(ahbm_clk) {RegEnable(slvbuf_error_in, 0.U, slvbuf_error_en.asBool())}
|
||||||
cmd_doneQ := withClock(ahbm_clk) {RegNext(Mux(cmd_done.asBool(),1.U,cmd_doneQ) & !cmd_done_rst, 0.U)}
|
cmd_doneQ := withClock(ahbm_clk) {RegNext(Mux(cmd_done.asBool(),1.U,cmd_doneQ) & !cmd_done_rst, 0.U)}
|
||||||
buf_cmd_byte_ptrQ := withClock(ahbm_clk) {RegEnable(buf_cmd_byte_ptr(2, 0), 0.U, buf_cmd_byte_ptr_en.asBool())}
|
buf_cmd_byte_ptrQ := withClock(ahbm_clk) {RegEnable(buf_cmd_byte_ptr(2, 0), 0.U, buf_cmd_byte_ptr_en.asBool())}
|
||||||
ahb_hready_q := withClock(ahbm_clk) {RegNext(io.ahb_hready, 0.U)}
|
ahb_hready_q := withClock(ahbm_clk) {RegNext(io.ahb.in.hready, 0.U)}
|
||||||
ahb_htrans_q := withClock(ahbm_clk) {RegNext(io.ahb_htrans(1, 0), 0.U)}
|
ahb_htrans_q := withClock(ahbm_clk) {RegNext(io.ahb.out.htrans(1, 0), 0.U)}
|
||||||
ahb_hwrite_q := withClock(ahbm_addr_clk) {RegNext(io.ahb_hwrite, 0.U)}
|
ahb_hwrite_q := withClock(ahbm_addr_clk) {RegNext(io.ahb.out.hwrite, 0.U)}
|
||||||
ahb_hresp_q := withClock(ahbm_clk) {RegNext(io.ahb_hresp, 0.U)}
|
ahb_hresp_q := withClock(ahbm_clk) {RegNext(io.ahb.in.hresp, 0.U)}
|
||||||
ahb_hrdata_q := withClock(ahbm_data_clk) {RegNext(io.ahb_hrdata(63, 0), 0.U)}
|
ahb_hrdata_q := withClock(ahbm_data_clk) {RegNext(io.ahb.in.hrdata(63, 0), 0.U)}
|
||||||
|
|
||||||
buf_clken := io.bus_clk_en & (buf_wr_en | slvbuf_wr_en | io.clk_override)
|
buf_clken := io.bus_clk_en & (buf_wr_en | slvbuf_wr_en | io.clk_override)
|
||||||
ahbm_addr_clken := io.bus_clk_en & ((io.ahb_hready & io.ahb_htrans(1)) | io.clk_override)
|
ahbm_addr_clken := io.bus_clk_en & ((io.ahb.in.hready & io.ahb.out.htrans(1)) | io.clk_override)
|
||||||
ahbm_data_clken := io.bus_clk_en & ((buf_state =/= idle) | io.clk_override)
|
ahbm_data_clken := io.bus_clk_en & ((buf_state =/= idle) | io.clk_override)
|
||||||
|
|
||||||
//Clkhdr
|
//Clkhdr
|
||||||
|
@ -411,3 +405,8 @@ class axi4_to_ahb extends Module with lib with RequireAsyncReset with Config {
|
||||||
ahbm_addr_clk := rvclkhdr(clock, ahbm_addr_clken, io.scan_mode)
|
ahbm_addr_clk := rvclkhdr(clock, ahbm_addr_clken, io.scan_mode)
|
||||||
ahbm_data_clk := rvclkhdr(clock, ahbm_data_clken, io.scan_mode)
|
ahbm_data_clk := rvclkhdr(clock, ahbm_data_clken, io.scan_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object AXImain extends App {
|
||||||
|
println("Generate Verilog")
|
||||||
|
println((new chisel3.stage.ChiselStage).emitVerilog(new axi4_to_ahb()))
|
||||||
|
}
|
|
@ -14,6 +14,11 @@ class quasar_bundle extends Bundle with lib{
|
||||||
val sb_axi = new axi_channels(SB_BUS_TAG)
|
val sb_axi = new axi_channels(SB_BUS_TAG)
|
||||||
val dma_axi = Flipped(new axi_channels(DMA_BUS_TAG))
|
val dma_axi = Flipped(new axi_channels(DMA_BUS_TAG))
|
||||||
|
|
||||||
|
val ahb = new ahb_channel
|
||||||
|
val lsu_ahb = new ahb_channel
|
||||||
|
val sb_ahb = new ahb_channel
|
||||||
|
val dma_ahb = Flipped(new ahb_channel)
|
||||||
|
|
||||||
val dbg_rst_l = Input(AsyncReset())
|
val dbg_rst_l = Input(AsyncReset())
|
||||||
val rst_vec = Input(UInt(31.W))
|
val rst_vec = Input(UInt(31.W))
|
||||||
val nmi_int = Input(Bool())
|
val nmi_int = Input(Bool())
|
||||||
|
@ -44,58 +49,59 @@ class quasar_bundle extends Bundle with lib{
|
||||||
val ic = new ic_mem()
|
val ic = new ic_mem()
|
||||||
val iccm = new iccm_mem()
|
val iccm = new iccm_mem()
|
||||||
|
|
||||||
// AHB Lite Bus
|
// // AHB Lite Bus
|
||||||
val haddr = Output(UInt(32.W))
|
// val haddr = Output(UInt(32.W))
|
||||||
val hburst = Output(UInt(3.W))
|
// val hburst = Output(UInt(3.W))
|
||||||
val hmastlock = Output(Bool())
|
// val hmastlock = Output(Bool())
|
||||||
val hprot = Output(UInt(4.W))
|
// val hprot = Output(UInt(4.W))
|
||||||
val hsize = Output(UInt(3.W))
|
// val hsize = Output(UInt(3.W))
|
||||||
val htrans = Output(UInt(2.W))
|
// val htrans = Output(UInt(2.W))
|
||||||
val hwrite = Output(Bool())
|
// val hwrite = Output(Bool())
|
||||||
val hrdata = Input(UInt(64.W))
|
// val hrdata = Input(UInt(64.W))
|
||||||
val hready = Input(Bool())
|
// val hready = Input(Bool())
|
||||||
val hresp = Input(Bool())
|
// val hresp = Input(Bool())
|
||||||
|
//
|
||||||
// AHB Master
|
// // AHB Master
|
||||||
val lsu_haddr = Output(UInt(32.W))
|
// val lsu_haddr = Output(UInt(32.W))
|
||||||
val lsu_hburst = Output(UInt(3.W))
|
// val lsu_hburst = Output(UInt(3.W))
|
||||||
val lsu_hmastlock = Output(Bool())
|
// val lsu_hmastlock = Output(Bool())
|
||||||
val lsu_hprot = Output(UInt(4.W))
|
// val lsu_hprot = Output(UInt(4.W))
|
||||||
val lsu_hsize = Output(UInt(3.W))
|
// val lsu_hsize = Output(UInt(3.W))
|
||||||
val lsu_htrans = Output(UInt(2.W))
|
// val lsu_htrans = Output(UInt(2.W))
|
||||||
val lsu_hwrite = Output(Bool())
|
// val lsu_hwrite = Output(Bool())
|
||||||
val lsu_hwdata = Output(UInt(64.W))
|
// val lsu_hwdata = Output(UInt(64.W))
|
||||||
val lsu_hrdata = Input(UInt(64.W))
|
// val lsu_hrdata = Input(UInt(64.W))
|
||||||
val lsu_hready = Input(Bool())
|
// val lsu_hready = Input(Bool())
|
||||||
val lsu_hresp = Input(Bool())
|
// val lsu_hresp = Input(Bool())
|
||||||
|
//
|
||||||
// System Bus Debug Master
|
// // System Bus Debug Master
|
||||||
val sb_haddr = Output(UInt(32.W))
|
// val sb_haddr = Output(UInt(32.W))
|
||||||
val sb_hburst = Output(UInt(3.W))
|
// val sb_hburst = Output(UInt(3.W))
|
||||||
val sb_hmastlock = Output(Bool())
|
// val sb_hmastlock = Output(Bool())
|
||||||
val sb_hprot = Output(UInt(4.W))
|
// val sb_hprot = Output(UInt(4.W))
|
||||||
val sb_hsize = Output(UInt(3.W))
|
// val sb_hsize = Output(UInt(3.W))
|
||||||
val sb_htrans = Output(UInt(2.W))
|
// val sb_htrans = Output(UInt(2.W))
|
||||||
val sb_hwrite = Output(Bool())
|
// val sb_hwrite = Output(Bool())
|
||||||
val sb_hwdata = Output(UInt(64.W))
|
// val sb_hwdata = Output(UInt(64.W))
|
||||||
val sb_hrdata = Input(UInt(64.W))
|
// val sb_hrdata = Input(UInt(64.W))
|
||||||
val sb_hready = Input(Bool())
|
// val sb_hready = Input(Bool())
|
||||||
val sb_hresp = Input(Bool())
|
// val sb_hresp = Input(Bool())
|
||||||
|
//
|
||||||
// DMA slave
|
// // DMA slave
|
||||||
val dma_hsel = Input(Bool())
|
val dma_hsel = Input(Bool())
|
||||||
val dma_haddr = Input(UInt(32.W))
|
// val dma_haddr = Input(UInt(32.W))
|
||||||
val dma_hburst = Input(UInt(3.W))
|
// val dma_hburst = Input(UInt(3.W))
|
||||||
val dma_hmastlock = Input(Bool())
|
// val dma_hmastlock = Input(Bool())
|
||||||
val dma_hprot = Input(UInt(4.W))
|
// val dma_hprot = Input(UInt(4.W))
|
||||||
val dma_hsize = Input(UInt(3.W))
|
// val dma_hsize = Input(UInt(3.W))
|
||||||
val dma_htrans = Input(UInt(2.W))
|
// val dma_htrans = Input(UInt(2.W))
|
||||||
val dma_hwrite = Input(Bool())
|
// val dma_hwrite = Input(Bool())
|
||||||
val dma_hwdata = Input(UInt(64.W))
|
// val dma_hwdata = Input(UInt(64.W))
|
||||||
val dma_hreadyin = Input(Bool())
|
val dma_hreadyin = Input(Bool())
|
||||||
val dma_hrdata = Output(UInt(64.W))
|
// val dma_hrdata = Output(UInt(64.W))
|
||||||
val dma_hreadyout = Output(Bool())
|
// val dma_hreadyout = Output(Bool())
|
||||||
val dma_hresp = Output(Bool())
|
// val dma_hresp = Output(Bool())
|
||||||
|
|
||||||
val lsu_bus_clk_en = Input(Bool())
|
val lsu_bus_clk_en = Input(Bool())
|
||||||
val ifu_bus_clk_en = Input(Bool())
|
val ifu_bus_clk_en = Input(Bool())
|
||||||
val dbg_bus_clk_en = Input(Bool())
|
val dbg_bus_clk_en = Input(Bool())
|
||||||
|
@ -317,9 +323,9 @@ class quasar extends Module with RequireAsyncReset with lib {
|
||||||
lsu_axi4_to_ahb.io.axi_arprot := io.lsu_axi.ar.bits.prot
|
lsu_axi4_to_ahb.io.axi_arprot := io.lsu_axi.ar.bits.prot
|
||||||
|
|
||||||
lsu_axi4_to_ahb.io.axi_rready := io.lsu_axi.r.ready
|
lsu_axi4_to_ahb.io.axi_rready := io.lsu_axi.r.ready
|
||||||
lsu_axi4_to_ahb.io.ahb_hrdata := io.lsu_hrdata
|
// lsu_axi4_to_ahb.io.ahb_hrdata := io.lsu_hrdata
|
||||||
lsu_axi4_to_ahb.io.ahb_hready := io.lsu_hready
|
// lsu_axi4_to_ahb.io.ahb_hready := io.lsu_hready
|
||||||
lsu_axi4_to_ahb.io.ahb_hresp := io.lsu_hresp
|
// lsu_axi4_to_ahb.io.ahb_hresp := io.lsu_hresp
|
||||||
|
|
||||||
val ifu_axi4_to_ahb = Module(new axi4_to_ahb())
|
val ifu_axi4_to_ahb = Module(new axi4_to_ahb())
|
||||||
ifu_axi4_to_ahb.io.axi_awvalid := io.ifu_axi.aw.valid
|
ifu_axi4_to_ahb.io.axi_awvalid := io.ifu_axi.aw.valid
|
||||||
|
@ -345,9 +351,9 @@ class quasar extends Module with RequireAsyncReset with lib {
|
||||||
|
|
||||||
ifu_axi4_to_ahb.io.axi_rready := io.ifu_axi.r.ready
|
ifu_axi4_to_ahb.io.axi_rready := io.ifu_axi.r.ready
|
||||||
|
|
||||||
ifu_axi4_to_ahb.io.ahb_hrdata := io.hrdata
|
// ifu_axi4_to_ahb.io.ahb_hrdata := io.hrdata
|
||||||
ifu_axi4_to_ahb.io.ahb_hready := io.hready
|
// ifu_axi4_to_ahb.io.ahb_hready := io.hready
|
||||||
ifu_axi4_to_ahb.io.ahb_hresp := io.hresp
|
// ifu_axi4_to_ahb.io.ahb_hresp := io.hresp
|
||||||
|
|
||||||
val sb_axi4_to_ahb = Module(new axi4_to_ahb())
|
val sb_axi4_to_ahb = Module(new axi4_to_ahb())
|
||||||
sb_axi4_to_ahb.io.axi_awvalid := io.sb_axi.aw.valid
|
sb_axi4_to_ahb.io.axi_awvalid := io.sb_axi.aw.valid
|
||||||
|
@ -372,9 +378,9 @@ class quasar extends Module with RequireAsyncReset with lib {
|
||||||
sb_axi4_to_ahb.io.axi_arprot := io.sb_axi.ar.bits.prot
|
sb_axi4_to_ahb.io.axi_arprot := io.sb_axi.ar.bits.prot
|
||||||
|
|
||||||
sb_axi4_to_ahb.io.axi_rready := io.sb_axi.r.ready
|
sb_axi4_to_ahb.io.axi_rready := io.sb_axi.r.ready
|
||||||
sb_axi4_to_ahb.io.ahb_hrdata := io.sb_hrdata
|
// sb_axi4_to_ahb.io.ahb_hrdata := io.sb_hrdata
|
||||||
sb_axi4_to_ahb.io.ahb_hready := io.sb_hready
|
// sb_axi4_to_ahb.io.ahb_hready := io.sb_hready
|
||||||
sb_axi4_to_ahb.io.ahb_hresp := io.sb_hresp
|
// sb_axi4_to_ahb.io.ahb_hresp := io.sb_hresp
|
||||||
|
|
||||||
val dma_ahb_to_axi4 = Module(new ahb_to_axi4())
|
val dma_ahb_to_axi4 = Module(new ahb_to_axi4())
|
||||||
dma_ahb_to_axi4.io.scan_mode := io.scan_mode
|
dma_ahb_to_axi4.io.scan_mode := io.scan_mode
|
||||||
|
@ -394,18 +400,16 @@ class quasar extends Module with RequireAsyncReset with lib {
|
||||||
dma_ahb_to_axi4.io.axi_rresp := io.dma_axi.r.bits.resp
|
dma_ahb_to_axi4.io.axi_rresp := io.dma_axi.r.bits.resp
|
||||||
|
|
||||||
// AHB-Lite signals
|
// AHB-Lite signals
|
||||||
dma_ahb_to_axi4.io.ahb_haddr := io.dma_haddr
|
// dma_ahb_to_axi4.io.ahb_haddr := io.dma_haddr
|
||||||
dma_ahb_to_axi4.io.ahb_hburst := io.dma_hburst
|
// dma_ahb_to_axi4.io.ahb_hburst := io.dma_hburst
|
||||||
dma_ahb_to_axi4.io.ahb_hmastlock := io.dma_hmastlock
|
// dma_ahb_to_axi4.io.ahb_hmastlock := io.dma_hmastlock
|
||||||
dma_ahb_to_axi4.io.ahb_hprot := io.dma_hprot
|
// dma_ahb_to_axi4.io.ahb_hprot := io.dma_hprot
|
||||||
dma_ahb_to_axi4.io.ahb_hsize := io.dma_hsize
|
// dma_ahb_to_axi4.io.ahb_hsize := io.dma_hsize
|
||||||
dma_ahb_to_axi4.io.ahb_htrans := io.dma_htrans
|
// dma_ahb_to_axi4.io.ahb_htrans := io.dma_htrans
|
||||||
dma_ahb_to_axi4.io.ahb_hwrite := io.dma_hwrite
|
// dma_ahb_to_axi4.io.ahb_hwrite := io.dma_hwrite
|
||||||
dma_ahb_to_axi4.io.ahb_hwdata := io.dma_hwdata
|
// dma_ahb_to_axi4.io.ahb_hwdata := io.dma_hwdata
|
||||||
dma_ahb_to_axi4.io.ahb_hsel := io.dma_hsel
|
dma_ahb_to_axi4.io.ahb_hsel := io.dma_hsel
|
||||||
dma_ahb_to_axi4.io.ahb_hreadyin := io.dma_hreadyin
|
dma_ahb_to_axi4.io.ahb_hreadyin := io.dma_hreadyin
|
||||||
|
|
||||||
// Mux for the axi-bridge
|
|
||||||
lsu.io.axi.aw.ready := Mux(BUILD_AHB_LITE.B, lsu_axi4_to_ahb.io.axi_awready, io.lsu_axi.aw.ready)
|
lsu.io.axi.aw.ready := Mux(BUILD_AHB_LITE.B, lsu_axi4_to_ahb.io.axi_awready, io.lsu_axi.aw.ready)
|
||||||
lsu.io.axi.w.ready := Mux(BUILD_AHB_LITE.B, lsu_axi4_to_ahb.io.axi_wready, io.lsu_axi.w.ready)
|
lsu.io.axi.w.ready := Mux(BUILD_AHB_LITE.B, lsu_axi4_to_ahb.io.axi_wready, io.lsu_axi.w.ready)
|
||||||
lsu.io.axi.b.valid := Mux(BUILD_AHB_LITE.B, lsu_axi4_to_ahb.io.axi_bvalid, io.lsu_axi.b.valid)
|
lsu.io.axi.b.valid := Mux(BUILD_AHB_LITE.B, lsu_axi4_to_ahb.io.axi_bvalid, io.lsu_axi.b.valid)
|
||||||
|
@ -450,77 +454,81 @@ class quasar extends Module with RequireAsyncReset with lib {
|
||||||
dma_ctrl.io.dma_axi.ar.bits.addr := Mux(BUILD_AHB_LITE.B, dma_ahb_to_axi4.io.axi_araddr, io.dma_axi.aw.bits.addr)
|
dma_ctrl.io.dma_axi.ar.bits.addr := Mux(BUILD_AHB_LITE.B, dma_ahb_to_axi4.io.axi_araddr, io.dma_axi.aw.bits.addr)
|
||||||
dma_ctrl.io.dma_axi.ar.bits.size := Mux(BUILD_AHB_LITE.B, dma_ahb_to_axi4.io.axi_arsize, io.dma_axi.aw.bits.size)
|
dma_ctrl.io.dma_axi.ar.bits.size := Mux(BUILD_AHB_LITE.B, dma_ahb_to_axi4.io.axi_arsize, io.dma_axi.aw.bits.size)
|
||||||
dma_ctrl.io.dma_axi.r.ready := Mux(BUILD_AHB_LITE.B, dma_ahb_to_axi4.io.axi_rready, io.dma_axi.r.ready)
|
dma_ctrl.io.dma_axi.r.ready := Mux(BUILD_AHB_LITE.B, dma_ahb_to_axi4.io.axi_rready, io.dma_axi.r.ready)
|
||||||
|
|
||||||
|
|
||||||
// AHB Signals
|
// AHB Signals
|
||||||
io.haddr := ifu_axi4_to_ahb.io.ahb_haddr
|
io.ahb <> ifu_axi4_to_ahb.io.ahb
|
||||||
io.hburst := ifu_axi4_to_ahb.io.ahb_hburst
|
// io.haddr := ifu_axi4_to_ahb.io.ahb_haddr
|
||||||
io.hmastlock := ifu_axi4_to_ahb.io.ahb_hmastlock
|
// io.hburst := ifu_axi4_to_ahb.io.ahb_hburst
|
||||||
io.hprot := ifu_axi4_to_ahb.io.ahb_hprot
|
// io.hmastlock := ifu_axi4_to_ahb.io.ahb_hmastlock
|
||||||
io.hsize := ifu_axi4_to_ahb.io.ahb_hsize
|
// io.hprot := ifu_axi4_to_ahb.io.ahb_hprot
|
||||||
io.htrans := ifu_axi4_to_ahb.io.ahb_htrans
|
// io.hsize := ifu_axi4_to_ahb.io.ahb_hsize
|
||||||
io.hwrite := ifu_axi4_to_ahb.io.ahb_hwrite
|
// io.htrans := ifu_axi4_to_ahb.io.ahb_htrans
|
||||||
|
// io.hwrite := ifu_axi4_to_ahb.io.ahb_hwrite
|
||||||
|
|
||||||
|
io.lsu_ahb <> lsu_axi4_to_ahb.io.ahb
|
||||||
|
// io.lsu_haddr := lsu_axi4_to_ahb.io.ahb_haddr
|
||||||
|
// io.lsu_hburst := lsu_axi4_to_ahb.io.ahb_hburst
|
||||||
|
// io.lsu_hmastlock := lsu_axi4_to_ahb.io.ahb_hmastlock
|
||||||
|
// io.lsu_hprot := lsu_axi4_to_ahb.io.ahb_hprot
|
||||||
|
// io.lsu_hsize := lsu_axi4_to_ahb.io.ahb_hsize
|
||||||
|
// io.lsu_htrans := lsu_axi4_to_ahb.io.ahb_htrans
|
||||||
|
// io.lsu_hwrite := lsu_axi4_to_ahb.io.ahb_hwrite
|
||||||
|
// io.lsu_hwdata := lsu_axi4_to_ahb.io.ahb_hwdata
|
||||||
|
|
||||||
io.lsu_haddr := lsu_axi4_to_ahb.io.ahb_haddr
|
io.sb_ahb <> sb_axi4_to_ahb.io.ahb
|
||||||
io.lsu_hburst := lsu_axi4_to_ahb.io.ahb_hburst
|
// io.sb_haddr := sb_axi4_to_ahb.io.ahb_haddr
|
||||||
io.lsu_hmastlock := lsu_axi4_to_ahb.io.ahb_hmastlock
|
// io.sb_hburst := sb_axi4_to_ahb.io.ahb_hburst
|
||||||
io.lsu_hprot := lsu_axi4_to_ahb.io.ahb_hprot
|
// io.sb_hmastlock := sb_axi4_to_ahb.io.ahb_hmastlock
|
||||||
io.lsu_hsize := lsu_axi4_to_ahb.io.ahb_hsize
|
// io.sb_hprot := sb_axi4_to_ahb.io.ahb_hprot
|
||||||
io.lsu_htrans := lsu_axi4_to_ahb.io.ahb_htrans
|
// io.sb_hsize := sb_axi4_to_ahb.io.ahb_hsize
|
||||||
io.lsu_hwrite := lsu_axi4_to_ahb.io.ahb_hwrite
|
// io.sb_htrans := sb_axi4_to_ahb.io.ahb_htrans
|
||||||
io.lsu_hwdata := lsu_axi4_to_ahb.io.ahb_hwdata
|
// io.sb_hwrite := sb_axi4_to_ahb.io.ahb_hwrite
|
||||||
|
// io.sb_hwdata := sb_axi4_to_ahb.io.ahb_hwdata
|
||||||
|
|
||||||
io.sb_haddr := sb_axi4_to_ahb.io.ahb_haddr
|
io.dma_ahb <> dma_ahb_to_axi4.io.ahb
|
||||||
io.sb_hburst := sb_axi4_to_ahb.io.ahb_hburst
|
// io.dma_hrdata := dma_ahb_to_axi4.io.ahb_hrdata
|
||||||
io.sb_hmastlock := sb_axi4_to_ahb.io.ahb_hmastlock
|
// io.dma_hreadyout := dma_ahb_to_axi4.io.ahb_hreadyout
|
||||||
io.sb_hprot := sb_axi4_to_ahb.io.ahb_hprot
|
// io.dma_hresp := dma_ahb_to_axi4.io.ahb_hresp
|
||||||
io.sb_hsize := sb_axi4_to_ahb.io.ahb_hsize
|
// io.dma_hresp := 0.U//dma_ahb_to_axi4.io.ahb_hrdata
|
||||||
io.sb_htrans := sb_axi4_to_ahb.io.ahb_htrans
|
// io.dmi_reg_rdata := 0.U//dma_ahb_to_axi4.io.ahb_rdata
|
||||||
io.sb_hwrite := sb_axi4_to_ahb.io.ahb_hwrite
|
|
||||||
io.sb_hwdata := sb_axi4_to_ahb.io.ahb_hwdata
|
|
||||||
|
|
||||||
io.dma_hrdata := dma_ahb_to_axi4.io.ahb_hrdata
|
|
||||||
io.dma_hreadyout := dma_ahb_to_axi4.io.ahb_hreadyout
|
|
||||||
io.dma_hresp := dma_ahb_to_axi4.io.ahb_hresp
|
|
||||||
}
|
}
|
||||||
.otherwise{
|
.otherwise{
|
||||||
// AHB Signals
|
// AHB Signals
|
||||||
io.haddr := 0.U
|
io.ahb.out <> 0.U.asTypeOf(io.ahb.out)
|
||||||
io.hburst := 0.U
|
// io.haddr := 0.U
|
||||||
io.hmastlock := 0.U
|
// io.hburst := 0.U
|
||||||
io.hprot := 0.U
|
// io.hmastlock := 0.U
|
||||||
io.hsize := 0.U
|
// io.hprot := 0.U
|
||||||
io.htrans := 0.U
|
// io.hsize := 0.U
|
||||||
io.hwrite := 0.U
|
// io.htrans := 0.U
|
||||||
|
// io.hwrite := 0.U
|
||||||
|
|
||||||
|
io.lsu_ahb.out <> 0.U.asTypeOf(io.lsu_ahb.out)
|
||||||
|
// io.lsu_haddr := 0.U
|
||||||
|
// io.lsu_hburst := 0.U
|
||||||
|
// io.lsu_hmastlock := 0.U
|
||||||
|
// io.lsu_hprot := 0.U
|
||||||
|
// io.lsu_hsize := 0.U
|
||||||
|
// io.lsu_htrans := 0.U
|
||||||
|
// io.lsu_hwrite := 0.U
|
||||||
|
// io.lsu_hwdata := 0.U
|
||||||
|
|
||||||
io.lsu_haddr := 0.U
|
io.sb_ahb.out <> 0.U.asTypeOf(io.sb_ahb.out)
|
||||||
io.lsu_hburst := 0.U
|
// io.sb_haddr := 0.U
|
||||||
io.lsu_hmastlock := 0.U
|
// io.sb_hburst := 0.U
|
||||||
io.lsu_hprot := 0.U
|
// io.sb_hmastlock := 0.U
|
||||||
io.lsu_hsize := 0.U
|
// io.sb_hprot := 0.U
|
||||||
io.lsu_htrans := 0.U
|
// io.sb_hsize := 0.U
|
||||||
io.lsu_hwrite := 0.U
|
// io.sb_htrans := 0.U
|
||||||
io.lsu_hwdata := 0.U
|
// io.sb_hwrite := 0.U
|
||||||
|
// io.sb_hwdata := 0.U
|
||||||
|
|
||||||
io.sb_haddr := 0.U
|
io.dma_ahb.in <> 0.U.asTypeOf(io.dma_ahb.in)
|
||||||
io.sb_hburst := 0.U
|
// io.dma_hrdata := 0.U
|
||||||
io.sb_hmastlock := 0.U
|
// io.dma_hreadyout := 0.U
|
||||||
io.sb_hprot := 0.U
|
// io.dma_hresp := 0.U
|
||||||
io.sb_hsize := 0.U
|
|
||||||
io.sb_htrans := 0.U
|
|
||||||
io.sb_hwrite := 0.U
|
|
||||||
io.sb_hwdata := 0.U
|
|
||||||
|
|
||||||
io.dma_hrdata := 0.U
|
|
||||||
io.dma_hreadyout := 0.U
|
|
||||||
io.dma_hresp := 0.U
|
|
||||||
}
|
}
|
||||||
|
|
||||||
io.dmi_reg_rdata := 0.U
|
io.dmi_reg_rdata := 0.U
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,18 +20,19 @@ class quasar_wrapper extends Module with lib with RequireAsyncReset {
|
||||||
|
|
||||||
// DMA slave
|
// DMA slave
|
||||||
val dma_hsel = Input(Bool())
|
val dma_hsel = Input(Bool())
|
||||||
val dma_haddr = Input(UInt(32.W))
|
val dma_ahb = Flipped(new ahb_channel())
|
||||||
val dma_hburst = Input(UInt(3.W))
|
// val dma_haddr = Input(UInt(32.W))
|
||||||
val dma_hmastlock = Input(Bool())
|
// val dma_hburst = Input(UInt(3.W))
|
||||||
val dma_hprot = Input(UInt(4.W))
|
// val dma_hmastlock = Input(Bool())
|
||||||
val dma_hsize = Input(UInt(3.W))
|
// val dma_hprot = Input(UInt(4.W))
|
||||||
val dma_htrans = Input(UInt(2.W))
|
// val dma_hsize = Input(UInt(3.W))
|
||||||
val dma_hwrite = Input(Bool())
|
// val dma_htrans = Input(UInt(2.W))
|
||||||
val dma_hwdata = Input(UInt(64.W))
|
// val dma_hwrite = Input(Bool())
|
||||||
|
// val dma_hwdata = Input(UInt(64.W))
|
||||||
val dma_hreadyin = Input(Bool())
|
val dma_hreadyin = Input(Bool())
|
||||||
val dma_hrdata = Output(UInt(64.W))
|
// val dma_hrdata = Output(UInt(64.W))
|
||||||
val dma_hreadyout = Output(Bool())
|
// val dma_hreadyout = Output(Bool())
|
||||||
val dma_hresp = Output(Bool())
|
// val dma_hresp = Output(Bool())
|
||||||
|
|
||||||
val lsu_bus_clk_en = Input(Bool())
|
val lsu_bus_clk_en = Input(Bool())
|
||||||
val ifu_bus_clk_en = Input(Bool())
|
val ifu_bus_clk_en = Input(Bool())
|
||||||
|
@ -74,127 +75,149 @@ class quasar_wrapper extends Module with lib with RequireAsyncReset {
|
||||||
val rv_trace_pkt = new trace_pkt_t()
|
val rv_trace_pkt = new trace_pkt_t()
|
||||||
val scan_mode = Input(Bool())
|
val scan_mode = Input(Bool())
|
||||||
|
|
||||||
})
|
})
|
||||||
val mem = Module(new quasar.mem())
|
val mem = Module(new quasar.mem())
|
||||||
val dmi_wrapper = Module(new dmi_wrapper())
|
val dmi_wrapper = Module(new dmi_wrapper())
|
||||||
val core = Module(new quasar())
|
val swerv = Module(new quasar())
|
||||||
dmi_wrapper.io.trst_n := io.jtag_trst_n
|
dmi_wrapper.io.trst_n := io.jtag_trst_n
|
||||||
dmi_wrapper.io.tck := io.jtag_tck
|
dmi_wrapper.io.tck := io.jtag_tck
|
||||||
dmi_wrapper.io.tms := io.jtag_tms
|
dmi_wrapper.io.tms := io.jtag_tms
|
||||||
dmi_wrapper.io.tdi := io.jtag_tdi
|
dmi_wrapper.io.tdi := io.jtag_tdi
|
||||||
dmi_wrapper.io.core_clk := clock
|
dmi_wrapper.io.core_clk := clock
|
||||||
dmi_wrapper.io.jtag_id := io.jtag_id
|
dmi_wrapper.io.jtag_id := io.jtag_id
|
||||||
dmi_wrapper.io.rd_data := core.io.dmi_reg_rdata
|
dmi_wrapper.io.rd_data := swerv.io.dmi_reg_rdata
|
||||||
|
|
||||||
|
|
||||||
dmi_wrapper.io.core_rst_n := io.dbg_rst_l
|
dmi_wrapper.io.core_rst_n := io.dbg_rst_l
|
||||||
core.io.dmi_reg_wdata := dmi_wrapper.io.reg_wr_data
|
swerv.io.dmi_reg_wdata := dmi_wrapper.io.reg_wr_data
|
||||||
core.io.dmi_reg_addr := dmi_wrapper.io.reg_wr_addr
|
swerv.io.dmi_reg_addr := dmi_wrapper.io.reg_wr_addr
|
||||||
core.io.dmi_reg_en := dmi_wrapper.io.reg_en
|
swerv.io.dmi_reg_en := dmi_wrapper.io.reg_en
|
||||||
core.io.dmi_reg_wr_en := dmi_wrapper.io.reg_wr_en
|
swerv.io.dmi_reg_wr_en := dmi_wrapper.io.reg_wr_en
|
||||||
core.io.dmi_hard_reset := dmi_wrapper.io.dmi_hard_reset
|
swerv.io.dmi_hard_reset := dmi_wrapper.io.dmi_hard_reset
|
||||||
io.jtag_tdo := dmi_wrapper.io.tdo
|
io.jtag_tdo := dmi_wrapper.io.tdo
|
||||||
|
|
||||||
// Memory signals
|
// Memory signals
|
||||||
mem.io.dccm_clk_override := core.io.dccm_clk_override
|
mem.io.dccm_clk_override := swerv.io.dccm_clk_override
|
||||||
mem.io.icm_clk_override := core.io.icm_clk_override
|
mem.io.icm_clk_override := swerv.io.icm_clk_override
|
||||||
mem.io.dec_tlu_core_ecc_disable := core.io.dec_tlu_core_ecc_disable
|
mem.io.dec_tlu_core_ecc_disable := swerv.io.dec_tlu_core_ecc_disable
|
||||||
mem.io.dccm <> core.io.dccm
|
mem.io.dccm <> swerv.io.dccm
|
||||||
mem.io.rst_l := reset
|
mem.io.rst_l := reset
|
||||||
mem.io.clk := clock
|
mem.io.clk := clock
|
||||||
mem.io.scan_mode := io.scan_mode
|
mem.io.scan_mode := io.scan_mode
|
||||||
// Memory outputs
|
// Memory outputs
|
||||||
core.io.dbg_rst_l := io.dbg_rst_l
|
swerv.io.dbg_rst_l := io.dbg_rst_l
|
||||||
core.io.ic <> mem.io.ic
|
swerv.io.ic <> mem.io.ic
|
||||||
core.io.iccm <> mem.io.iccm
|
swerv.io.iccm <> mem.io.iccm
|
||||||
core.io.sb_hready := 0.U
|
|
||||||
core.io.hrdata := 0.U
|
swerv.io.ahb.in <> 0.U.asTypeOf(swerv.io.ahb.in)
|
||||||
core.io.sb_hresp := 0.U
|
swerv.io.lsu_ahb.in <> 0.U.asTypeOf(swerv.io.lsu_ahb.in)
|
||||||
core.io.lsu_hrdata := 0.U
|
swerv.io.sb_ahb.in <> 0.U.asTypeOf(swerv.io.sb_ahb.in)
|
||||||
core.io.lsu_hresp := 0.U
|
io.dma_ahb.in <> 0.U.asTypeOf(io.dma_ahb.in)
|
||||||
core.io.lsu_hready := 0.U
|
// swerv.io.sb_hready := 0.U
|
||||||
core.io.hready := 0.U
|
// swerv.io.hrdata := 0.U
|
||||||
core.io.hresp := 0.U
|
// swerv.io.sb_hresp := 0.U
|
||||||
core.io.sb_hrdata := 0.U
|
// swerv.io.lsu_hrdata := 0.U
|
||||||
core.io.scan_mode := io.scan_mode
|
// swerv.io.lsu_hresp := 0.U
|
||||||
|
// swerv.io.lsu_hready := 0.U
|
||||||
|
// swerv.io.hready := 0.U
|
||||||
|
// swerv.io.hresp := 0.U
|
||||||
|
// swerv.io.sb_hrdata := 0.U
|
||||||
|
swerv.io.scan_mode := io.scan_mode
|
||||||
// SweRV Inputs
|
// SweRV Inputs
|
||||||
core.io.dbg_rst_l := io.dbg_rst_l
|
swerv.io.dbg_rst_l := io.dbg_rst_l
|
||||||
core.io.rst_vec := io.rst_vec
|
swerv.io.rst_vec := io.rst_vec
|
||||||
core.io.nmi_int := io.nmi_int
|
swerv.io.nmi_int := io.nmi_int
|
||||||
core.io.nmi_vec := io.nmi_vec
|
swerv.io.nmi_vec := io.nmi_vec
|
||||||
|
|
||||||
// external halt/run interface
|
// external halt/run interface
|
||||||
core.io.i_cpu_halt_req := io.i_cpu_halt_req
|
swerv.io.i_cpu_halt_req := io.i_cpu_halt_req
|
||||||
core.io.i_cpu_run_req := io.i_cpu_run_req
|
swerv.io.i_cpu_run_req := io.i_cpu_run_req
|
||||||
core.io.core_id := io.core_id
|
swerv.io.core_id := io.core_id
|
||||||
|
|
||||||
// external MPC halt/run interface
|
// external MPC halt/run interface
|
||||||
core.io.mpc_debug_halt_req := io.mpc_debug_halt_req
|
swerv.io.mpc_debug_halt_req := io.mpc_debug_halt_req
|
||||||
core.io.mpc_debug_run_req := io.mpc_debug_run_req
|
swerv.io.mpc_debug_run_req := io.mpc_debug_run_req
|
||||||
core.io.mpc_reset_run_req := io.mpc_reset_run_req
|
swerv.io.mpc_reset_run_req := io.mpc_reset_run_req
|
||||||
|
|
||||||
//-------------------------- LSU AXI signals--------------------------
|
//-------------------------- LSU AXI signals--------------------------
|
||||||
// AXI Write Channels
|
// AXI Write Channels
|
||||||
core.io.lsu_axi <> io.lsu_axi
|
swerv.io.lsu_axi <> io.lsu_axi
|
||||||
//-------------------------- IFU AXI signals--------------------------
|
//-------------------------- IFU AXI signals--------------------------
|
||||||
// AXI Write Channels
|
// AXI Write Channels
|
||||||
core.io.ifu_axi <> io.ifu_axi
|
swerv.io.ifu_axi <> io.ifu_axi
|
||||||
//-------------------------- SB AXI signals--------------------------
|
//-------------------------- SB AXI signals--------------------------
|
||||||
// AXI Write Channels
|
// AXI Write Channels
|
||||||
core.io.sb_axi <> io.sb_axi
|
swerv.io.sb_axi <> io.sb_axi
|
||||||
|
|
||||||
//-------------------------- DMA AXI signals--------------------------
|
//-------------------------- DMA AXI signals--------------------------
|
||||||
// AXI Write Channels
|
// AXI Write Channels
|
||||||
core.io.dma_axi <> io.dma_axi
|
swerv.io.dma_axi <> io.dma_axi
|
||||||
|
|
||||||
// DMA Slave
|
// DMA Slave
|
||||||
core.io.dma_hsel := io.dma_hsel
|
swerv.io.dma_hsel := io.dma_hsel
|
||||||
core.io.dma_haddr := io.dma_haddr
|
swerv.io.dma_ahb.out <> io.dma_ahb.out
|
||||||
core.io.dma_hburst := io.dma_hburst
|
// swerv.io.dma_haddr := io.dma_haddr
|
||||||
core.io.dma_hmastlock := io.dma_hmastlock
|
// swerv.io.dma_hburst := io.dma_hburst
|
||||||
core.io.dma_hprot := io.dma_hprot
|
// swerv.io.dma_hmastlock := io.dma_hmastlock
|
||||||
core.io.dma_hsize := io.dma_hsize
|
// swerv.io.dma_hprot := io.dma_hprot
|
||||||
core.io.dma_htrans := io.dma_htrans
|
// swerv.io.dma_hsize := io.dma_hsize
|
||||||
core.io.dma_hwrite := io.dma_hwrite
|
// swerv.io.dma_htrans := io.dma_htrans
|
||||||
core.io.dma_hwdata := io.dma_hwdata
|
// swerv.io.dma_hwrite := io.dma_hwrite
|
||||||
core.io.dma_hreadyin := io.dma_hreadyin
|
// swerv.io.dma_hwdata := io.dma_hwdata
|
||||||
|
swerv.io.dma_hreadyin := io.dma_hreadyin
|
||||||
|
|
||||||
core.io.lsu_bus_clk_en := io.lsu_bus_clk_en
|
swerv.io.lsu_bus_clk_en
|
||||||
core.io.ifu_bus_clk_en := io.ifu_bus_clk_en
|
swerv.io.ifu_bus_clk_en
|
||||||
core.io.dbg_bus_clk_en := io.dbg_bus_clk_en
|
swerv.io.dbg_bus_clk_en
|
||||||
core.io.dma_bus_clk_en := io.dma_bus_clk_en
|
swerv.io.dma_bus_clk_en
|
||||||
|
|
||||||
core.io.timer_int := io.timer_int
|
swerv.io.dmi_reg_en
|
||||||
core.io.soft_int := io.soft_int
|
swerv.io.dmi_reg_addr
|
||||||
core.io.extintsrc_req := io.extintsrc_req
|
swerv.io.dmi_reg_wr_en
|
||||||
|
swerv.io.dmi_reg_wdata
|
||||||
|
swerv.io.dmi_hard_reset
|
||||||
|
|
||||||
|
swerv.io.extintsrc_req
|
||||||
|
swerv.io.timer_int
|
||||||
|
swerv.io.soft_int
|
||||||
|
swerv.io.scan_mode
|
||||||
|
|
||||||
|
swerv.io.lsu_bus_clk_en := io.lsu_bus_clk_en
|
||||||
|
swerv.io.ifu_bus_clk_en := io.ifu_bus_clk_en
|
||||||
|
swerv.io.dbg_bus_clk_en := io.dbg_bus_clk_en
|
||||||
|
swerv.io.dma_bus_clk_en := io.dma_bus_clk_en
|
||||||
|
|
||||||
|
swerv.io.timer_int := io.timer_int
|
||||||
|
swerv.io.soft_int := io.soft_int
|
||||||
|
swerv.io.extintsrc_req := io.extintsrc_req
|
||||||
|
|
||||||
// Outputs
|
// Outputs
|
||||||
val core_rst_l = core.io.core_rst_l
|
val core_rst_l = swerv.io.core_rst_l
|
||||||
io.rv_trace_pkt := core.io.rv_trace_pkt
|
io.rv_trace_pkt := swerv.io.rv_trace_pkt
|
||||||
|
|
||||||
// external halt/run interface
|
// external halt/run interface
|
||||||
io.o_cpu_halt_ack := core.io.o_cpu_halt_ack
|
io.o_cpu_halt_ack := swerv.io.o_cpu_halt_ack
|
||||||
io.o_cpu_halt_status := core.io.o_cpu_halt_status
|
io.o_cpu_halt_status := swerv.io.o_cpu_halt_status
|
||||||
io.o_cpu_run_ack := core.io.o_cpu_run_ack
|
io.o_cpu_run_ack := swerv.io.o_cpu_run_ack
|
||||||
io.o_debug_mode_status := core.io.o_debug_mode_status
|
io.o_debug_mode_status := swerv.io.o_debug_mode_status
|
||||||
|
|
||||||
io.mpc_debug_halt_ack := core.io.mpc_debug_halt_ack
|
io.mpc_debug_halt_ack := swerv.io.mpc_debug_halt_ack
|
||||||
io.mpc_debug_run_ack := core.io.mpc_debug_run_ack
|
io.mpc_debug_run_ack := swerv.io.mpc_debug_run_ack
|
||||||
io.debug_brkpt_status := core.io.debug_brkpt_status
|
io.debug_brkpt_status := swerv.io.debug_brkpt_status
|
||||||
|
|
||||||
io.dec_tlu_perfcnt0 := core.io.dec_tlu_perfcnt0
|
io.dec_tlu_perfcnt0 := swerv.io.dec_tlu_perfcnt0
|
||||||
io.dec_tlu_perfcnt1 := core.io.dec_tlu_perfcnt1
|
io.dec_tlu_perfcnt1 := swerv.io.dec_tlu_perfcnt1
|
||||||
io.dec_tlu_perfcnt2 := core.io.dec_tlu_perfcnt2
|
io.dec_tlu_perfcnt2 := swerv.io.dec_tlu_perfcnt2
|
||||||
io.dec_tlu_perfcnt3 := core.io.dec_tlu_perfcnt3
|
io.dec_tlu_perfcnt3 := swerv.io.dec_tlu_perfcnt3
|
||||||
|
|
||||||
|
|
||||||
//-------------------------- LSU AXI signals--------------------------
|
//-------------------------- LSU AXI signals--------------------------
|
||||||
// AXI Write Channels
|
// AXI Write Channels
|
||||||
|
|
||||||
// DMA Slave
|
// DMA Slave
|
||||||
io.dma_hrdata := core.io.dma_hrdata
|
// io.dma_hrdata := swerv.io.dma_hrdata
|
||||||
io.dma_hreadyout := core.io.dma_hreadyout
|
// io.dma_hreadyout := swerv.io.dma_hreadyout
|
||||||
io.dma_hresp := core.io.dma_hresp
|
// io.dma_hresp := swerv.io.dma_hresp
|
||||||
|
|
||||||
}
|
}
|
||||||
object QUASAR_Wrp extends App {
|
object QUASAR_Wrp extends App {
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue