Revert "Fix whitespace in src_Core directory."
This reverts commit a137a6ede7.
This commit is contained in:
@@ -21,9 +21,9 @@ import AXI4_Types :: *;
|
||||
// we get exactly the signals specified in the ARM spec.
|
||||
|
||||
interface AXI4_Stream_Master_IFC #(numeric type wd_id,
|
||||
numeric type wd_dest,
|
||||
numeric type wd_data,
|
||||
numeric type wd_user);
|
||||
numeric type wd_dest,
|
||||
numeric type wd_data,
|
||||
numeric type wd_user);
|
||||
|
||||
(* always_ready, result="tvalid" *) method Bool m_tvalid; // out
|
||||
(* always_ready, result="tid" *) method Bit #(wd_id) m_tid; // out
|
||||
@@ -45,18 +45,18 @@ endinterface: AXI4_Stream_Master_IFC
|
||||
// we get exactly the signals specified in the ARM spec.
|
||||
|
||||
interface AXI4_Stream_Slave_IFC #(numeric type wd_id,
|
||||
numeric type wd_dest,
|
||||
numeric type wd_data,
|
||||
numeric type wd_user);
|
||||
numeric type wd_dest,
|
||||
numeric type wd_data,
|
||||
numeric type wd_user);
|
||||
(* always_ready, always_enabled, prefix = "" *)
|
||||
method Action m_tvalid ((* port="tvalid" *) Bool tvalid, // in
|
||||
(* port="tid" *) Bit #(wd_id) tid, // in
|
||||
(* port="tdata" *) Bit #(wd_data) tdata, // in
|
||||
(* port="tstrb" *) Bit #(TDiv #(wd_data,8)) tstrb, // in
|
||||
(* port="tkeep" *) Bit #(TDiv #(wd_data,8)) tkeep, // in
|
||||
(* port="tlast" *) Bool tlast, // in
|
||||
(* port="tdest" *) Bit #(wd_dest) tdest, // in
|
||||
(* port="tuser" *) Bit #(wd_user) tuser); // in
|
||||
(* port="tid" *) Bit #(wd_id) tid, // in
|
||||
(* port="tdata" *) Bit #(wd_data) tdata, // in
|
||||
(* port="tstrb" *) Bit #(TDiv #(wd_data,8)) tstrb, // in
|
||||
(* port="tkeep" *) Bit #(TDiv #(wd_data,8)) tkeep, // in
|
||||
(* port="tlast" *) Bool tlast, // in
|
||||
(* port="tdest" *) Bit #(wd_dest) tdest, // in
|
||||
(* port="tuser" *) Bit #(wd_user) tuser); // in
|
||||
(* always_ready, result="tready" *)
|
||||
method Bool m_tready; // out
|
||||
endinterface: AXI4_Stream_Slave_IFC
|
||||
@@ -65,32 +65,32 @@ endinterface: AXI4_Stream_Slave_IFC
|
||||
// Connecting signal-level interfaces
|
||||
|
||||
instance Connectable #(AXI4_Stream_Master_IFC #(wd_id, wd_dest, wd_data, wd_user),
|
||||
AXI4_Stream_Slave_IFC #(wd_id, wd_dest, wd_data, wd_user));
|
||||
AXI4_Stream_Slave_IFC #(wd_id, wd_dest, wd_data, wd_user));
|
||||
|
||||
module mkConnection #(AXI4_Stream_Master_IFC #(wd_id, wd_dest, wd_data, wd_user) axim,
|
||||
AXI4_Stream_Slave_IFC #(wd_id, wd_dest, wd_data, wd_user) axis)
|
||||
(Empty);
|
||||
AXI4_Stream_Slave_IFC #(wd_id, wd_dest, wd_data, wd_user) axis)
|
||||
(Empty);
|
||||
|
||||
(* fire_when_enabled, no_implicit_conditions *)
|
||||
rule rl_data_channel;
|
||||
axis.m_tvalid (axim.m_tvalid,
|
||||
axim.m_tid,
|
||||
axim.m_tdata,
|
||||
axim.m_tstrb,
|
||||
axim.m_tkeep,
|
||||
axim.m_tlast,
|
||||
axim.m_tdest,
|
||||
axim.m_tuser);
|
||||
axim.m_tready (axis.m_tready);
|
||||
axis.m_tvalid (axim.m_tvalid,
|
||||
axim.m_tid,
|
||||
axim.m_tdata,
|
||||
axim.m_tstrb,
|
||||
axim.m_tkeep,
|
||||
axim.m_tlast,
|
||||
axim.m_tdest,
|
||||
axim.m_tuser);
|
||||
axim.m_tready (axis.m_tready);
|
||||
endrule
|
||||
endmodule
|
||||
endinstance
|
||||
|
||||
instance Connectable #(AXI4_Stream_Slave_IFC #(wd_id, wd_dest, wd_data, wd_user),
|
||||
AXI4_Stream_Master_IFC #(wd_id, wd_dest, wd_data, wd_user));
|
||||
AXI4_Stream_Master_IFC #(wd_id, wd_dest, wd_data, wd_user));
|
||||
module mkConnection #(AXI4_Stream_Slave_IFC #(wd_id, wd_dest, wd_data, wd_user) axis,
|
||||
AXI4_Stream_Master_IFC #(wd_id, wd_dest, wd_data, wd_user) axim)
|
||||
(Empty);
|
||||
AXI4_Stream_Master_IFC #(wd_id, wd_dest, wd_data, wd_user) axim)
|
||||
(Empty);
|
||||
mkConnection(axim, axis);
|
||||
endmodule
|
||||
endinstance
|
||||
@@ -117,17 +117,17 @@ AXI4_Stream_Master_IFC #(wd_id, wd_dest, wd_data, wd_user) axi4_stream_dummy_mas
|
||||
|
||||
AXI4_Stream_Slave_IFC #(wd_id, wd_dest, wd_data, wd_user) axi4_stream_dummy_slave
|
||||
= interface AXI4_Stream_Slave_IFC
|
||||
method Action m_tvalid (wvalid,
|
||||
wid,
|
||||
wdata,
|
||||
wstrb,
|
||||
wkeep,
|
||||
wlast,
|
||||
wdest,
|
||||
wuser);
|
||||
noAction;
|
||||
endmethod
|
||||
method Bool m_tready = True;
|
||||
method Action m_tvalid (wvalid,
|
||||
wid,
|
||||
wdata,
|
||||
wstrb,
|
||||
wkeep,
|
||||
wlast,
|
||||
wdest,
|
||||
wuser);
|
||||
noAction;
|
||||
endmethod
|
||||
method Bool m_tready = True;
|
||||
endinterface;
|
||||
|
||||
// ****************************************************************
|
||||
@@ -143,28 +143,28 @@ AXI4_Stream_Slave_IFC #(wd_id, wd_dest, wd_data, wd_user) axi4_stream_dummy_slav
|
||||
|
||||
function FIFOF_I #(t) fn_crg_and_rg_to_FIFOF_I (Reg #(Bool) rg_full, Reg #(t) rg_data);
|
||||
return interface FIFOF_I;
|
||||
method Action enq (t x) if (! rg_full);
|
||||
rg_full <= True;
|
||||
rg_data <= x;
|
||||
endmethod
|
||||
method Bool notFull;
|
||||
return (! rg_full);
|
||||
endmethod
|
||||
endinterface;
|
||||
method Action enq (t x) if (! rg_full);
|
||||
rg_full <= True;
|
||||
rg_data <= x;
|
||||
endmethod
|
||||
method Bool notFull;
|
||||
return (! rg_full);
|
||||
endmethod
|
||||
endinterface;
|
||||
endfunction
|
||||
|
||||
function FIFOF_O #(t) fn_crg_and_rg_to_FIFOF_O (Reg #(Bool) rg_full, Reg #(t) rg_data);
|
||||
return interface FIFOF_O;
|
||||
method t first () if (rg_full);
|
||||
return rg_data;
|
||||
endmethod
|
||||
method Action deq () if (rg_full);
|
||||
rg_full <= False;
|
||||
endmethod
|
||||
method notEmpty;
|
||||
return rg_full;
|
||||
endmethod
|
||||
endinterface;
|
||||
method t first () if (rg_full);
|
||||
return rg_data;
|
||||
endmethod
|
||||
method Action deq () if (rg_full);
|
||||
rg_full <= False;
|
||||
endmethod
|
||||
method notEmpty;
|
||||
return rg_full;
|
||||
endmethod
|
||||
endinterface;
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -179,18 +179,18 @@ typedef struct {
|
||||
Bit #(wd_dest) tdest;
|
||||
Bit #(wd_user) tuser;
|
||||
} AXI4_Stream #(numeric type wd_id,
|
||||
numeric type wd_dest,
|
||||
numeric type wd_data,
|
||||
numeric type wd_user)
|
||||
numeric type wd_dest,
|
||||
numeric type wd_data,
|
||||
numeric type wd_user)
|
||||
deriving (Bits, FShow);
|
||||
|
||||
// ================================================================
|
||||
// Master transactor interface
|
||||
|
||||
interface AXI4_Stream_Master_Xactor_IFC #(numeric type wd_id,
|
||||
numeric type wd_dest,
|
||||
numeric type wd_data,
|
||||
numeric type wd_user);
|
||||
numeric type wd_dest,
|
||||
numeric type wd_data,
|
||||
numeric type wd_user);
|
||||
method Action reset;
|
||||
// AXI side
|
||||
interface AXI4_Stream_Master_IFC #(wd_id, wd_dest, wd_data, wd_user) axi_side;
|
||||
@@ -220,18 +220,18 @@ module mkAXI4_Stream_Master_Xactor (AXI4_Stream_Master_Xactor_IFC #(wd_id, wd_de
|
||||
|
||||
// AXI side
|
||||
interface axi_side = interface AXI4_Stream_Master_IFC;
|
||||
method m_tvalid = f_data.notEmpty;
|
||||
method m_tid = f_data.first.tid;
|
||||
method m_tdata = f_data.first.tdata;
|
||||
method m_tstrb = f_data.first.tstrb;
|
||||
method m_tkeep = f_data.first.tkeep;
|
||||
method m_tlast = f_data.first.tlast;
|
||||
method m_tdest = f_data.first.tdest;
|
||||
method m_tuser = f_data.first.tuser;
|
||||
method Action m_tready (Bool tready);
|
||||
if (f_data.notEmpty && tready) f_data.deq;
|
||||
endmethod
|
||||
endinterface;
|
||||
method m_tvalid = f_data.notEmpty;
|
||||
method m_tid = f_data.first.tid;
|
||||
method m_tdata = f_data.first.tdata;
|
||||
method m_tstrb = f_data.first.tstrb;
|
||||
method m_tkeep = f_data.first.tkeep;
|
||||
method m_tlast = f_data.first.tlast;
|
||||
method m_tdest = f_data.first.tdest;
|
||||
method m_tuser = f_data.first.tuser;
|
||||
method Action m_tready (Bool tready);
|
||||
if (f_data.notEmpty && tready) f_data.deq;
|
||||
endmethod
|
||||
endinterface;
|
||||
|
||||
// FIFOF side
|
||||
interface i_stream = to_FIFOF_I (f_data);
|
||||
@@ -241,9 +241,9 @@ endmodule: mkAXI4_Stream_Master_Xactor
|
||||
// Slave transactor interface
|
||||
|
||||
interface AXI4_Stream_Slave_Xactor_IFC #(numeric type wd_id,
|
||||
numeric type wd_dest,
|
||||
numeric type wd_data,
|
||||
numeric type wd_user);
|
||||
numeric type wd_dest,
|
||||
numeric type wd_data,
|
||||
numeric type wd_user);
|
||||
method Action reset;
|
||||
// AXI side
|
||||
interface AXI4_Stream_Slave_IFC #(wd_id, wd_dest, wd_data, wd_user) axi_side;
|
||||
@@ -272,28 +272,28 @@ module mkAXI4_Stream_Slave_Xactor (AXI4_Stream_Slave_Xactor_IFC #(wd_id, wd_dest
|
||||
|
||||
// AXI side
|
||||
interface axi_side = interface AXI4_Stream_Slave_IFC;
|
||||
method Action m_tvalid (Bool tvalid,
|
||||
Bit #(wd_id) tid,
|
||||
Bit #(wd_data) tdata,
|
||||
Bit #(TDiv #(wd_data, 8)) tstrb,
|
||||
Bit #(TDiv #(wd_data, 8)) tkeep,
|
||||
Bool tlast,
|
||||
Bit #(wd_dest) tdest,
|
||||
Bit #(wd_user) tuser);
|
||||
if (tvalid && f_data.notFull)
|
||||
f_data.enq (AXI4_Stream {tid: tid,
|
||||
tdata: tdata,
|
||||
tstrb: tstrb,
|
||||
tkeep: tkeep,
|
||||
tlast: tlast,
|
||||
tdest: tdest,
|
||||
tuser: tuser});
|
||||
endmethod
|
||||
method Action m_tvalid (Bool tvalid,
|
||||
Bit #(wd_id) tid,
|
||||
Bit #(wd_data) tdata,
|
||||
Bit #(TDiv #(wd_data, 8)) tstrb,
|
||||
Bit #(TDiv #(wd_data, 8)) tkeep,
|
||||
Bool tlast,
|
||||
Bit #(wd_dest) tdest,
|
||||
Bit #(wd_user) tuser);
|
||||
if (tvalid && f_data.notFull)
|
||||
f_data.enq (AXI4_Stream {tid: tid,
|
||||
tdata: tdata,
|
||||
tstrb: tstrb,
|
||||
tkeep: tkeep,
|
||||
tlast: tlast,
|
||||
tdest: tdest,
|
||||
tuser: tuser});
|
||||
endmethod
|
||||
|
||||
method Bool m_tready;
|
||||
return f_data.notFull;
|
||||
endmethod
|
||||
endinterface;
|
||||
method Bool m_tready;
|
||||
return f_data.notFull;
|
||||
endmethod
|
||||
endinterface;
|
||||
|
||||
// FIFOF side
|
||||
interface o_stream = to_FIFOF_O (f_data);
|
||||
@@ -347,92 +347,92 @@ module mkAXI4_Master_Xactor_2 (AXI4_Master_Xactor_IFC #(wd_id, wd_dest, wd_data,
|
||||
|
||||
// AXI side
|
||||
interface axi_side = interface AXI4_Master_IFC;
|
||||
// Wr Addr channel
|
||||
method Bool m_awvalid = crg_wr_addr_full [port_deq];
|
||||
method Bit #(wd_id) m_awid = rg_wr_addr.awid;
|
||||
method Bit #(wd_dest) m_awaddr = rg_wr_addr.awaddr;
|
||||
method Bit #(8) m_awlen = rg_wr_addr.awlen;
|
||||
method AXI4_Size m_awsize = rg_wr_addr.awsize;
|
||||
method Bit #(2) m_awburst = rg_wr_addr.awburst;
|
||||
method Bit #(1) m_awlock = rg_wr_addr.awlock;
|
||||
method Bit #(4) m_awcache = rg_wr_addr.awcache;
|
||||
method Bit #(3) m_awprot = rg_wr_addr.awprot;
|
||||
method Bit #(4) m_awqos = rg_wr_addr.awqos;
|
||||
method Bit #(4) m_awregion = rg_wr_addr.awregion;
|
||||
method Bit #(wd_user) m_awuser = rg_wr_addr.awuser;
|
||||
method Action m_awready (Bool awready);
|
||||
if (crg_wr_addr_full [port_deq] && awready)
|
||||
crg_wr_addr_full [port_deq] <= False; // deq
|
||||
endmethod
|
||||
// Wr Addr channel
|
||||
method Bool m_awvalid = crg_wr_addr_full [port_deq];
|
||||
method Bit #(wd_id) m_awid = rg_wr_addr.awid;
|
||||
method Bit #(wd_dest) m_awaddr = rg_wr_addr.awaddr;
|
||||
method Bit #(8) m_awlen = rg_wr_addr.awlen;
|
||||
method AXI4_Size m_awsize = rg_wr_addr.awsize;
|
||||
method Bit #(2) m_awburst = rg_wr_addr.awburst;
|
||||
method Bit #(1) m_awlock = rg_wr_addr.awlock;
|
||||
method Bit #(4) m_awcache = rg_wr_addr.awcache;
|
||||
method Bit #(3) m_awprot = rg_wr_addr.awprot;
|
||||
method Bit #(4) m_awqos = rg_wr_addr.awqos;
|
||||
method Bit #(4) m_awregion = rg_wr_addr.awregion;
|
||||
method Bit #(wd_user) m_awuser = rg_wr_addr.awuser;
|
||||
method Action m_awready (Bool awready);
|
||||
if (crg_wr_addr_full [port_deq] && awready)
|
||||
crg_wr_addr_full [port_deq] <= False; // deq
|
||||
endmethod
|
||||
|
||||
// Wr Data channel
|
||||
method Bool m_wvalid = crg_wr_data_full [port_deq];
|
||||
method Bit #(wd_id) m_wid = rg_wr_data.wid;
|
||||
method Bit #(wd_data) m_wdata = rg_wr_data.wdata;
|
||||
method Bit #(TDiv #(wd_data, 8)) m_wstrb = rg_wr_data.wstrb;
|
||||
method Bool m_wlast = rg_wr_data.wlast;
|
||||
method Bit #(wd_user) m_wuser = rg_wr_data.wuser;
|
||||
method Action m_wready (Bool wready);
|
||||
if (crg_wr_data_full [port_deq] && wready)
|
||||
crg_wr_data_full [port_deq] <= False;
|
||||
endmethod
|
||||
// Wr Data channel
|
||||
method Bool m_wvalid = crg_wr_data_full [port_deq];
|
||||
method Bit #(wd_id) m_wid = rg_wr_data.wid;
|
||||
method Bit #(wd_data) m_wdata = rg_wr_data.wdata;
|
||||
method Bit #(TDiv #(wd_data, 8)) m_wstrb = rg_wr_data.wstrb;
|
||||
method Bool m_wlast = rg_wr_data.wlast;
|
||||
method Bit #(wd_user) m_wuser = rg_wr_data.wuser;
|
||||
method Action m_wready (Bool wready);
|
||||
if (crg_wr_data_full [port_deq] && wready)
|
||||
crg_wr_data_full [port_deq] <= False;
|
||||
endmethod
|
||||
|
||||
// Wr Response channel
|
||||
method Action m_bvalid (Bool bvalid,
|
||||
Bit #(wd_id) bid,
|
||||
Bit #(2) bresp,
|
||||
Bit #(wd_user) buser);
|
||||
if (bvalid && (! (crg_wr_resp_full [port_enq]))) begin
|
||||
crg_wr_resp_full [port_enq] <= True;
|
||||
rg_wr_resp <= AXI4_Wr_Resp {bid: bid,
|
||||
bresp: bresp,
|
||||
buser: buser};
|
||||
end
|
||||
endmethod
|
||||
// Wr Response channel
|
||||
method Action m_bvalid (Bool bvalid,
|
||||
Bit #(wd_id) bid,
|
||||
Bit #(2) bresp,
|
||||
Bit #(wd_user) buser);
|
||||
if (bvalid && (! (crg_wr_resp_full [port_enq]))) begin
|
||||
crg_wr_resp_full [port_enq] <= True;
|
||||
rg_wr_resp <= AXI4_Wr_Resp {bid: bid,
|
||||
bresp: bresp,
|
||||
buser: buser};
|
||||
end
|
||||
endmethod
|
||||
|
||||
method Bool m_bready;
|
||||
return (! (crg_wr_resp_full [port_enq]));
|
||||
endmethod
|
||||
method Bool m_bready;
|
||||
return (! (crg_wr_resp_full [port_enq]));
|
||||
endmethod
|
||||
|
||||
// Rd Addr channel
|
||||
method Bool m_arvalid = crg_rd_addr_full [port_deq];
|
||||
method Bit #(wd_id) m_arid = rg_rd_addr.arid;
|
||||
method Bit #(wd_dest) m_araddr = rg_rd_addr.araddr;
|
||||
method Bit #(8) m_arlen = rg_rd_addr.arlen;
|
||||
method AXI4_Size m_arsize = rg_rd_addr.arsize;
|
||||
method Bit #(2) m_arburst = rg_rd_addr.arburst;
|
||||
method Bit #(1) m_arlock = rg_rd_addr.arlock;
|
||||
method Bit #(4) m_arcache = rg_rd_addr.arcache;
|
||||
method Bit #(3) m_arprot = rg_rd_addr.arprot;
|
||||
method Bit #(4) m_arqos = rg_rd_addr.arqos;
|
||||
method Bit #(4) m_arregion = rg_rd_addr.arregion;
|
||||
method Bit #(wd_user) m_aruser = rg_rd_addr.aruser;
|
||||
method Action m_arready (Bool arready);
|
||||
if (crg_rd_addr_full [port_deq] && arready)
|
||||
crg_rd_addr_full [port_deq] <= False; // deq
|
||||
endmethod
|
||||
// Rd Addr channel
|
||||
method Bool m_arvalid = crg_rd_addr_full [port_deq];
|
||||
method Bit #(wd_id) m_arid = rg_rd_addr.arid;
|
||||
method Bit #(wd_dest) m_araddr = rg_rd_addr.araddr;
|
||||
method Bit #(8) m_arlen = rg_rd_addr.arlen;
|
||||
method AXI4_Size m_arsize = rg_rd_addr.arsize;
|
||||
method Bit #(2) m_arburst = rg_rd_addr.arburst;
|
||||
method Bit #(1) m_arlock = rg_rd_addr.arlock;
|
||||
method Bit #(4) m_arcache = rg_rd_addr.arcache;
|
||||
method Bit #(3) m_arprot = rg_rd_addr.arprot;
|
||||
method Bit #(4) m_arqos = rg_rd_addr.arqos;
|
||||
method Bit #(4) m_arregion = rg_rd_addr.arregion;
|
||||
method Bit #(wd_user) m_aruser = rg_rd_addr.aruser;
|
||||
method Action m_arready (Bool arready);
|
||||
if (crg_rd_addr_full [port_deq] && arready)
|
||||
crg_rd_addr_full [port_deq] <= False; // deq
|
||||
endmethod
|
||||
|
||||
// Rd Data channel
|
||||
method Action m_rvalid (Bool rvalid,
|
||||
Bit #(wd_id) rid,
|
||||
Bit #(wd_data) rdata,
|
||||
Bit #(2) rresp,
|
||||
Bool rlast,
|
||||
Bit #(wd_user) ruser);
|
||||
if (rvalid && (! (crg_rd_data_full [port_enq])))
|
||||
crg_rd_data_full [port_enq] <= True;
|
||||
rg_rd_data <= (AXI4_Rd_Data {rid: rid,
|
||||
rdata: rdata,
|
||||
rresp: rresp,
|
||||
rlast: rlast,
|
||||
ruser: ruser});
|
||||
endmethod
|
||||
// Rd Data channel
|
||||
method Action m_rvalid (Bool rvalid,
|
||||
Bit #(wd_id) rid,
|
||||
Bit #(wd_data) rdata,
|
||||
Bit #(2) rresp,
|
||||
Bool rlast,
|
||||
Bit #(wd_user) ruser);
|
||||
if (rvalid && (! (crg_rd_data_full [port_enq])))
|
||||
crg_rd_data_full [port_enq] <= True;
|
||||
rg_rd_data <= (AXI4_Rd_Data {rid: rid,
|
||||
rdata: rdata,
|
||||
rresp: rresp,
|
||||
rlast: rlast,
|
||||
ruser: ruser});
|
||||
endmethod
|
||||
|
||||
method Bool m_rready;
|
||||
return (! (crg_rd_data_full [port_enq]));
|
||||
endmethod
|
||||
method Bool m_rready;
|
||||
return (! (crg_rd_data_full [port_enq]));
|
||||
endmethod
|
||||
|
||||
endinterface;
|
||||
endinterface;
|
||||
|
||||
// FIFOF side
|
||||
interface i_wr_addr = fn_crg_and_rg_to_FIFOF_I (crg_wr_addr_full [port_enq], rg_wr_addr);
|
||||
@@ -447,9 +447,9 @@ endmodule: mkAXI4_Master_Xactor_2
|
||||
// Slave transactor interface
|
||||
|
||||
interface AXI4_Slave_Xactor_IFC #(numeric type wd_id,
|
||||
numeric type wd_dest,
|
||||
numeric type wd_data,
|
||||
numeric type wd_user);
|
||||
numeric type wd_dest,
|
||||
numeric type wd_data,
|
||||
numeric type wd_user);
|
||||
method Action reset;
|
||||
|
||||
// AXI side
|
||||
@@ -493,109 +493,109 @@ module mkAXI4_Slave_Xactor (AXI4_Slave_Xactor_IFC #(wd_id, wd_dest, wd_data, wd_
|
||||
endmethod
|
||||
// AXI side
|
||||
interface axi_side = interface AXI4_Slave_IFC;
|
||||
// Wr Addr channel
|
||||
method Action m_awvalid (Bool awvalid,
|
||||
Bit #(wd_id) awid,
|
||||
Bit #(wd_dest) awaddr,
|
||||
Bit #(8) awlen,
|
||||
AXI4_Size awsize,
|
||||
Bit #(2) awburst,
|
||||
Bit #(1) awlock,
|
||||
Bit #(4) awcache,
|
||||
Bit #(3) awprot,
|
||||
Bit #(4) awqos,
|
||||
Bit #(4) awregion,
|
||||
Bit #(wd_user) awuser);
|
||||
if (awvalid && f_wr_addr.notFull)
|
||||
f_wr_addr.enq (AXI4_Wr_Addr {awid: awid,
|
||||
awaddr: awaddr,
|
||||
awlen: awlen,
|
||||
awsize: awsize,
|
||||
awburst: awburst,
|
||||
awlock: awlock,
|
||||
awcache: awcache,
|
||||
awprot: awprot,
|
||||
awqos: awqos,
|
||||
awregion: awregion,
|
||||
awuser: awuser});
|
||||
endmethod
|
||||
// Wr Addr channel
|
||||
method Action m_awvalid (Bool awvalid,
|
||||
Bit #(wd_id) awid,
|
||||
Bit #(wd_dest) awaddr,
|
||||
Bit #(8) awlen,
|
||||
AXI4_Size awsize,
|
||||
Bit #(2) awburst,
|
||||
Bit #(1) awlock,
|
||||
Bit #(4) awcache,
|
||||
Bit #(3) awprot,
|
||||
Bit #(4) awqos,
|
||||
Bit #(4) awregion,
|
||||
Bit #(wd_user) awuser);
|
||||
if (awvalid && f_wr_addr.notFull)
|
||||
f_wr_addr.enq (AXI4_Wr_Addr {awid: awid,
|
||||
awaddr: awaddr,
|
||||
awlen: awlen,
|
||||
awsize: awsize,
|
||||
awburst: awburst,
|
||||
awlock: awlock,
|
||||
awcache: awcache,
|
||||
awprot: awprot,
|
||||
awqos: awqos,
|
||||
awregion: awregion,
|
||||
awuser: awuser});
|
||||
endmethod
|
||||
|
||||
method Bool m_awready;
|
||||
return f_wr_addr.notFull;
|
||||
endmethod
|
||||
method Bool m_awready;
|
||||
return f_wr_addr.notFull;
|
||||
endmethod
|
||||
|
||||
// Wr Data channel
|
||||
method Action m_wvalid (Bool wvalid,
|
||||
Bit #(wd_id) wid,
|
||||
Bit #(wd_data) wdata,
|
||||
it #(TDiv #(wd_data, 8)) wstrb,
|
||||
Bool wlast,
|
||||
Bit #(wd_user) wuser);
|
||||
if (wvalid && f_wr_data.notFull)
|
||||
f_wr_data.enq (AXI4_Wr_Data {wid: wid,
|
||||
wdata: wdata,
|
||||
wstrb: wstrb,
|
||||
wlast: wlast,
|
||||
wuser: wuser});
|
||||
endmethod
|
||||
// Wr Data channel
|
||||
method Action m_wvalid (Bool wvalid,
|
||||
Bit #(wd_id) wid,
|
||||
Bit #(wd_data) wdata,
|
||||
it #(TDiv #(wd_data, 8)) wstrb,
|
||||
Bool wlast,
|
||||
Bit #(wd_user) wuser);
|
||||
if (wvalid && f_wr_data.notFull)
|
||||
f_wr_data.enq (AXI4_Wr_Data {wid: wid,
|
||||
wdata: wdata,
|
||||
wstrb: wstrb,
|
||||
wlast: wlast,
|
||||
wuser: wuser});
|
||||
endmethod
|
||||
|
||||
method Bool m_wready;
|
||||
return f_wr_data.notFull;
|
||||
endmethod
|
||||
method Bool m_wready;
|
||||
return f_wr_data.notFull;
|
||||
endmethod
|
||||
|
||||
// Wr Response channel
|
||||
method Bool m_bvalid = f_wr_resp.notEmpty;
|
||||
method Bit #(wd_id) m_bid = f_wr_resp.first.bid;
|
||||
method Bit #(2) m_bresp = f_wr_resp.first.bresp;
|
||||
method Bit #(wd_user) m_buser = f_wr_resp.first.buser;
|
||||
method Action m_bready (Bool bready);
|
||||
if (bready && f_wr_resp.notEmpty)
|
||||
f_wr_resp.deq;
|
||||
endmethod
|
||||
// Wr Response channel
|
||||
method Bool m_bvalid = f_wr_resp.notEmpty;
|
||||
method Bit #(wd_id) m_bid = f_wr_resp.first.bid;
|
||||
method Bit #(2) m_bresp = f_wr_resp.first.bresp;
|
||||
method Bit #(wd_user) m_buser = f_wr_resp.first.buser;
|
||||
method Action m_bready (Bool bready);
|
||||
if (bready && f_wr_resp.notEmpty)
|
||||
f_wr_resp.deq;
|
||||
endmethod
|
||||
|
||||
// Rd Addr channel
|
||||
method Action m_arvalid (Bool arvalid,
|
||||
Bit #(wd_id) arid,
|
||||
Bit #(wd_dest) araddr,
|
||||
Bit #(8) arlen,
|
||||
AXI4_Size arsize,
|
||||
Bit #(2) arburst,
|
||||
Bit #(1) arlock,
|
||||
Bit #(4) arcache,
|
||||
Bit #(3) arprot,
|
||||
Bit #(4) arqos,
|
||||
Bit #(4) arregion,
|
||||
Bit #(wd_user) aruser);
|
||||
if (arvalid && f_rd_addr.notFull)
|
||||
f_rd_addr.enq (AXI4_Rd_Addr {arid: arid,
|
||||
araddr: araddr,
|
||||
arlen: arlen,
|
||||
arsize: arsize,
|
||||
arburst: arburst,
|
||||
arlock: arlock,
|
||||
arcache: arcache,
|
||||
arprot: arprot,
|
||||
arqos: arqos,
|
||||
arregion: arregion,
|
||||
aruser: aruser});
|
||||
endmethod
|
||||
// Rd Addr channel
|
||||
method Action m_arvalid (Bool arvalid,
|
||||
Bit #(wd_id) arid,
|
||||
Bit #(wd_dest) araddr,
|
||||
Bit #(8) arlen,
|
||||
AXI4_Size arsize,
|
||||
Bit #(2) arburst,
|
||||
Bit #(1) arlock,
|
||||
Bit #(4) arcache,
|
||||
Bit #(3) arprot,
|
||||
Bit #(4) arqos,
|
||||
Bit #(4) arregion,
|
||||
Bit #(wd_user) aruser);
|
||||
if (arvalid && f_rd_addr.notFull)
|
||||
f_rd_addr.enq (AXI4_Rd_Addr {arid: arid,
|
||||
araddr: araddr,
|
||||
arlen: arlen,
|
||||
arsize: arsize,
|
||||
arburst: arburst,
|
||||
arlock: arlock,
|
||||
arcache: arcache,
|
||||
arprot: arprot,
|
||||
arqos: arqos,
|
||||
arregion: arregion,
|
||||
aruser: aruser});
|
||||
endmethod
|
||||
|
||||
method Bool m_arready;
|
||||
return f_rd_addr.notFull;
|
||||
endmethod
|
||||
method Bool m_arready;
|
||||
return f_rd_addr.notFull;
|
||||
endmethod
|
||||
|
||||
// Rd Data channel
|
||||
method Bool m_rvalid = f_rd_data.notEmpty;
|
||||
method Bit #(wd_id) m_rid = f_rd_data.first.rid;
|
||||
method Bit #(wd_data) m_rdata = f_rd_data.first.rdata;
|
||||
method Bit #(2) m_rresp = f_rd_data.first.rresp;
|
||||
method Bool m_rlast = f_rd_data.first.rlast;
|
||||
method Bit #(wd_user) m_ruser = f_rd_data.first.ruser;
|
||||
method Action m_rready (Bool rready);
|
||||
if (rready && f_rd_data.notEmpty)
|
||||
f_rd_data.deq;
|
||||
endmethod
|
||||
endinterface;
|
||||
// Rd Data channel
|
||||
method Bool m_rvalid = f_rd_data.notEmpty;
|
||||
method Bit #(wd_id) m_rid = f_rd_data.first.rid;
|
||||
method Bit #(wd_data) m_rdata = f_rd_data.first.rdata;
|
||||
method Bit #(2) m_rresp = f_rd_data.first.rresp;
|
||||
method Bool m_rlast = f_rd_data.first.rlast;
|
||||
method Bit #(wd_user) m_ruser = f_rd_data.first.ruser;
|
||||
method Action m_rready (Bool rready);
|
||||
if (rready && f_rd_data.notEmpty)
|
||||
f_rd_data.deq;
|
||||
endmethod
|
||||
endinterface;
|
||||
|
||||
// FIFOF side
|
||||
interface o_wr_addr = to_FIFOF_O (f_wr_addr);
|
||||
@@ -650,116 +650,116 @@ module mkAXI4_Slave_Xactor_2 (AXI4_Slave_Xactor_IFC #(wd_id, wd_dest, wd_data, w
|
||||
|
||||
// AXI side
|
||||
interface axi_side = interface AXI4_Slave_IFC;
|
||||
// Wr Addr channel
|
||||
method Action m_awvalid (Bool awvalid,
|
||||
Bit #(wd_id) awid,
|
||||
Bit #(wd_dest) awaddr,
|
||||
Bit #(8) awlen,
|
||||
AXI4_Size awsize,
|
||||
Bit #(2) awburst,
|
||||
Bit #(1) awlock,
|
||||
Bit #(4) awcache,
|
||||
Bit #(3) awprot,
|
||||
Bit #(4) awqos,
|
||||
Bit #(4) awregion,
|
||||
Bit #(wd_user) awuser);
|
||||
// Wr Addr channel
|
||||
method Action m_awvalid (Bool awvalid,
|
||||
Bit #(wd_id) awid,
|
||||
Bit #(wd_dest) awaddr,
|
||||
Bit #(8) awlen,
|
||||
AXI4_Size awsize,
|
||||
Bit #(2) awburst,
|
||||
Bit #(1) awlock,
|
||||
Bit #(4) awcache,
|
||||
Bit #(3) awprot,
|
||||
Bit #(4) awqos,
|
||||
Bit #(4) awregion,
|
||||
Bit #(wd_user) awuser);
|
||||
|
||||
if (awvalid && (! crg_wr_addr_full [port_enq])) begin
|
||||
crg_wr_addr_full [port_enq] <= True; // enq
|
||||
rg_wr_addr <= AXI4_Wr_Addr {awid: awid,
|
||||
awaddr: awaddr,
|
||||
awlen: awlen,
|
||||
awsize: awsize,
|
||||
awburst: awburst,
|
||||
awlock: awlock,
|
||||
awcache: awcache,
|
||||
awprot: awprot,
|
||||
awqos: awqos,
|
||||
awregion: awregion,
|
||||
awuser: awuser};
|
||||
end
|
||||
endmethod
|
||||
if (awvalid && (! crg_wr_addr_full [port_enq])) begin
|
||||
crg_wr_addr_full [port_enq] <= True; // enq
|
||||
rg_wr_addr <= AXI4_Wr_Addr {awid: awid,
|
||||
awaddr: awaddr,
|
||||
awlen: awlen,
|
||||
awsize: awsize,
|
||||
awburst: awburst,
|
||||
awlock: awlock,
|
||||
awcache: awcache,
|
||||
awprot: awprot,
|
||||
awqos: awqos,
|
||||
awregion: awregion,
|
||||
awuser: awuser};
|
||||
end
|
||||
endmethod
|
||||
|
||||
method Bool m_awready;
|
||||
return (! crg_wr_addr_full [port_enq]);
|
||||
endmethod
|
||||
method Bool m_awready;
|
||||
return (! crg_wr_addr_full [port_enq]);
|
||||
endmethod
|
||||
|
||||
// Wr Data channel
|
||||
method Action m_wvalid (Bool wvalid,
|
||||
Bit #(wd_id) wid,
|
||||
Bit #(wd_data) wdata,
|
||||
Bit #(TDiv #(wd_data, 8)) wstrb,
|
||||
Bool wlast,
|
||||
Bit #(wd_user) wuser);
|
||||
if (wvalid && (! crg_wr_data_full [port_enq])) begin
|
||||
crg_wr_data_full [port_enq] <= True; // enq
|
||||
rg_wr_data <= AXI4_Wr_Data {wid: wid,
|
||||
wdata: wdata,
|
||||
wstrb: wstrb,
|
||||
wlast: wlast,
|
||||
wuser: wuser};
|
||||
end
|
||||
endmethod
|
||||
// Wr Data channel
|
||||
method Action m_wvalid (Bool wvalid,
|
||||
Bit #(wd_id) wid,
|
||||
Bit #(wd_data) wdata,
|
||||
Bit #(TDiv #(wd_data, 8)) wstrb,
|
||||
Bool wlast,
|
||||
Bit #(wd_user) wuser);
|
||||
if (wvalid && (! crg_wr_data_full [port_enq])) begin
|
||||
crg_wr_data_full [port_enq] <= True; // enq
|
||||
rg_wr_data <= AXI4_Wr_Data {wid: wid,
|
||||
wdata: wdata,
|
||||
wstrb: wstrb,
|
||||
wlast: wlast,
|
||||
wuser: wuser};
|
||||
end
|
||||
endmethod
|
||||
|
||||
method Bool m_wready;
|
||||
return (! crg_wr_data_full [port_enq]);
|
||||
endmethod
|
||||
method Bool m_wready;
|
||||
return (! crg_wr_data_full [port_enq]);
|
||||
endmethod
|
||||
|
||||
// Wr Response channel
|
||||
method Bool m_bvalid = crg_wr_resp_full [port_deq];
|
||||
method Bit #(wd_id) m_bid = rg_wr_resp.bid;
|
||||
method Bit #(2) m_bresp = rg_wr_resp.bresp;
|
||||
method Bit #(wd_user) m_buser = rg_wr_resp.buser;
|
||||
method Action m_bready (Bool bready);
|
||||
if (bready && crg_wr_resp_full [port_deq])
|
||||
crg_wr_resp_full [port_deq] <= False; // deq
|
||||
endmethod
|
||||
// Wr Response channel
|
||||
method Bool m_bvalid = crg_wr_resp_full [port_deq];
|
||||
method Bit #(wd_id) m_bid = rg_wr_resp.bid;
|
||||
method Bit #(2) m_bresp = rg_wr_resp.bresp;
|
||||
method Bit #(wd_user) m_buser = rg_wr_resp.buser;
|
||||
method Action m_bready (Bool bready);
|
||||
if (bready && crg_wr_resp_full [port_deq])
|
||||
crg_wr_resp_full [port_deq] <= False; // deq
|
||||
endmethod
|
||||
|
||||
// Rd Addr channel
|
||||
method Action m_arvalid (Bool arvalid,
|
||||
Bit #(wd_id) arid,
|
||||
Bit #(wd_dest) araddr,
|
||||
Bit #(8) arlen,
|
||||
AXI4_Size arsize,
|
||||
Bit #(2) arburst,
|
||||
Bit #(1) arlock,
|
||||
Bit #(4) arcache,
|
||||
Bit #(3) arprot,
|
||||
Bit #(4) arqos,
|
||||
Bit #(4) arregion,
|
||||
Bit #(wd_user) aruser);
|
||||
if (arvalid && (! crg_rd_addr_full [port_enq])) begin
|
||||
crg_rd_addr_full [port_enq] <= True; // enq
|
||||
rg_rd_addr <= AXI4_Rd_Addr {arid: arid,
|
||||
araddr: araddr,
|
||||
arlen: arlen,
|
||||
arsize: arsize,
|
||||
arburst: arburst,
|
||||
arlock: arlock,
|
||||
arcache: arcache,
|
||||
arprot: arprot,
|
||||
arqos: arqos,
|
||||
arregion: arregion,
|
||||
aruser: aruser};
|
||||
end
|
||||
endmethod
|
||||
// Rd Addr channel
|
||||
method Action m_arvalid (Bool arvalid,
|
||||
Bit #(wd_id) arid,
|
||||
Bit #(wd_dest) araddr,
|
||||
Bit #(8) arlen,
|
||||
AXI4_Size arsize,
|
||||
Bit #(2) arburst,
|
||||
Bit #(1) arlock,
|
||||
Bit #(4) arcache,
|
||||
Bit #(3) arprot,
|
||||
Bit #(4) arqos,
|
||||
Bit #(4) arregion,
|
||||
Bit #(wd_user) aruser);
|
||||
if (arvalid && (! crg_rd_addr_full [port_enq])) begin
|
||||
crg_rd_addr_full [port_enq] <= True; // enq
|
||||
rg_rd_addr <= AXI4_Rd_Addr {arid: arid,
|
||||
araddr: araddr,
|
||||
arlen: arlen,
|
||||
arsize: arsize,
|
||||
arburst: arburst,
|
||||
arlock: arlock,
|
||||
arcache: arcache,
|
||||
arprot: arprot,
|
||||
arqos: arqos,
|
||||
arregion: arregion,
|
||||
aruser: aruser};
|
||||
end
|
||||
endmethod
|
||||
|
||||
method Bool m_arready;
|
||||
return (! crg_rd_addr_full [port_enq]);
|
||||
endmethod
|
||||
method Bool m_arready;
|
||||
return (! crg_rd_addr_full [port_enq]);
|
||||
endmethod
|
||||
|
||||
// Rd Data channel
|
||||
method Bool m_rvalid = crg_rd_data_full [port_deq];
|
||||
method Bit #(wd_id) m_rid = rg_rd_data.rid;
|
||||
method Bit #(wd_data) m_rdata = rg_rd_data.rdata;
|
||||
method Bit #(2) m_rresp = rg_rd_data.rresp;
|
||||
method Bool m_rlast = rg_rd_data.rlast;
|
||||
method Bit #(wd_user) m_ruser = rg_rd_data.ruser;
|
||||
method Action m_rready (Bool rready);
|
||||
if (rready && crg_rd_data_full [port_deq])
|
||||
crg_rd_data_full [port_deq] <= False; // deq
|
||||
endmethod
|
||||
endinterface;
|
||||
// Rd Data channel
|
||||
method Bool m_rvalid = crg_rd_data_full [port_deq];
|
||||
method Bit #(wd_id) m_rid = rg_rd_data.rid;
|
||||
method Bit #(wd_data) m_rdata = rg_rd_data.rdata;
|
||||
method Bit #(2) m_rresp = rg_rd_data.rresp;
|
||||
method Bool m_rlast = rg_rd_data.rlast;
|
||||
method Bit #(wd_user) m_ruser = rg_rd_data.ruser;
|
||||
method Action m_rready (Bool rready);
|
||||
if (rready && crg_rd_data_full [port_deq])
|
||||
crg_rd_data_full [port_deq] <= False; // deq
|
||||
endmethod
|
||||
endinterface;
|
||||
|
||||
// FIFOF side
|
||||
interface o_wr_addr = fn_crg_and_rg_to_FIFOF_O (crg_wr_addr_full [port_deq], rg_wr_addr);
|
||||
|
||||
@@ -49,8 +49,8 @@ endfunction
|
||||
// Update an n-byte word taking into account an n-bit strobe
|
||||
|
||||
function Bit# (TMul #(n,8)) fn_update_strobed_bytes (Bit# (TMul #(n,8)) old_data,
|
||||
Bit# (TMul #(n,8)) new_data,
|
||||
Bit #(n) strobe);
|
||||
Bit# (TMul #(n,8)) new_data,
|
||||
Bit #(n) strobe);
|
||||
Bit# (TMul #(n,8)) mask = fn_strobe_to_mask (strobe);
|
||||
return ((old_data & (~ mask)) | (new_data & mask));
|
||||
endfunction
|
||||
@@ -68,8 +68,8 @@ endfunction
|
||||
// 32b version
|
||||
|
||||
function Tuple3 #(Bool, //
|
||||
Bit #(4), // strobe
|
||||
Bit #(32)) // lane-adjusted data
|
||||
Bit #(4), // strobe
|
||||
Bit #(32)) // lane-adjusted data
|
||||
fn_lane_adjust_32b (Bit #(32) addr, Bit #(3) dw, Bit #(32) data);
|
||||
|
||||
Bit #(4) strobe = 0;
|
||||
@@ -77,20 +77,20 @@ function Tuple3 #(Bool, //
|
||||
|
||||
case (dw)
|
||||
1: case (addr [1:0])
|
||||
2'b00: begin strobe = 'b_0001; end
|
||||
2'b01: begin strobe = 'b_0010; data = (data << 8); end
|
||||
2'b10: begin strobe = 'b_0100; data = (data << 16); end
|
||||
2'b11: begin strobe = 'b_1000; data = (data << 24); end
|
||||
endcase
|
||||
2'b00: begin strobe = 'b_0001; end
|
||||
2'b01: begin strobe = 'b_0010; data = (data << 8); end
|
||||
2'b10: begin strobe = 'b_0100; data = (data << 16); end
|
||||
2'b11: begin strobe = 'b_1000; data = (data << 24); end
|
||||
endcase
|
||||
2: case (addr [1:0])
|
||||
2'b00: begin strobe = 'b_0011; end
|
||||
2'b10: begin strobe = 'b_1100; data = (data << 16); end
|
||||
default: err = True;
|
||||
endcase
|
||||
2'b00: begin strobe = 'b_0011; end
|
||||
2'b10: begin strobe = 'b_1100; data = (data << 16); end
|
||||
default: err = True;
|
||||
endcase
|
||||
4: case (addr [1:0])
|
||||
2'b00: strobe = 'b_1111;
|
||||
default: err = True;
|
||||
endcase
|
||||
2'b00: strobe = 'b_1111;
|
||||
default: err = True;
|
||||
endcase
|
||||
default: err = True;
|
||||
endcase
|
||||
return tuple3 (err, strobe, data);
|
||||
@@ -100,8 +100,8 @@ endfunction
|
||||
// 64b version
|
||||
|
||||
function Tuple3 #(Bool, // err: misaligned, or bad data_width
|
||||
Bit #(8), // strobe
|
||||
Bit #(64)) // lane-adjusted data
|
||||
Bit #(8), // strobe
|
||||
Bit #(64)) // lane-adjusted data
|
||||
fn_lane_adjust_64b (Bit #(64) addr, Bit #(4) dw, Bit #(64) data);
|
||||
|
||||
Bit #(8) strobe = 0;
|
||||
@@ -109,31 +109,31 @@ function Tuple3 #(Bool, // err: misaligned, or bad data_width
|
||||
|
||||
case (dw)
|
||||
1: case (addr [2:0])
|
||||
3'b000: begin strobe = 'b_0000_0001; end
|
||||
3'b001: begin strobe = 'b_0000_0010; data = (data << 8); end
|
||||
3'b010: begin strobe = 'b_0000_0100; data = (data << 16); end
|
||||
3'b011: begin strobe = 'b_0000_1000; data = (data << 24); end
|
||||
3'b100: begin strobe = 'b_0001_0000; data = (data << 32); end
|
||||
3'b101: begin strobe = 'b_0010_0000; data = (data << 40); end
|
||||
3'b110: begin strobe = 'b_0100_0000; data = (data << 48); end
|
||||
3'b111: begin strobe = 'b_1000_0000; data = (data << 56); end
|
||||
endcase
|
||||
3'b000: begin strobe = 'b_0000_0001; end
|
||||
3'b001: begin strobe = 'b_0000_0010; data = (data << 8); end
|
||||
3'b010: begin strobe = 'b_0000_0100; data = (data << 16); end
|
||||
3'b011: begin strobe = 'b_0000_1000; data = (data << 24); end
|
||||
3'b100: begin strobe = 'b_0001_0000; data = (data << 32); end
|
||||
3'b101: begin strobe = 'b_0010_0000; data = (data << 40); end
|
||||
3'b110: begin strobe = 'b_0100_0000; data = (data << 48); end
|
||||
3'b111: begin strobe = 'b_1000_0000; data = (data << 56); end
|
||||
endcase
|
||||
2: case (addr [2:0])
|
||||
3'b000: begin strobe = 'b_0000_0011; end
|
||||
3'b010: begin strobe = 'b_0000_1100; data = (data << 16); end
|
||||
3'b100: begin strobe = 'b_0011_0000; data = (data << 32); end
|
||||
3'b110: begin strobe = 'b_1100_0000; data = (data << 48); end
|
||||
default: err = True;
|
||||
endcase
|
||||
3'b000: begin strobe = 'b_0000_0011; end
|
||||
3'b010: begin strobe = 'b_0000_1100; data = (data << 16); end
|
||||
3'b100: begin strobe = 'b_0011_0000; data = (data << 32); end
|
||||
3'b110: begin strobe = 'b_1100_0000; data = (data << 48); end
|
||||
default: err = True;
|
||||
endcase
|
||||
3: case (addr [2:0])
|
||||
3'b000: begin strobe = 'b_0000_1111; end
|
||||
3'b100: begin strobe = 'b_1111_0000; data = (data << 32); end
|
||||
default: err = True;
|
||||
endcase
|
||||
3'b000: begin strobe = 'b_0000_1111; end
|
||||
3'b100: begin strobe = 'b_1111_0000; data = (data << 32); end
|
||||
default: err = True;
|
||||
endcase
|
||||
4: case (addr [2:0])
|
||||
3'b000: begin strobe = 'b_1111_1111; end
|
||||
default: err = True;
|
||||
endcase
|
||||
3'b000: begin strobe = 'b_1111_1111; end
|
||||
default: err = True;
|
||||
endcase
|
||||
default: err = True;
|
||||
endcase
|
||||
return tuple3 (err, strobe, data);
|
||||
@@ -146,27 +146,27 @@ endfunction
|
||||
// 32b version
|
||||
|
||||
function Tuple2 #(Bool, // err: misaligned, or bad data_width
|
||||
Bit #(32)) // lane-unadjusted data
|
||||
Bit #(32)) // lane-unadjusted data
|
||||
fn_lane_unadjust_32b (Bit #(32) addr, Bit #(3) dw, Bit #(32) data);
|
||||
|
||||
Bool err = False;
|
||||
|
||||
case (dw)
|
||||
1: case (addr [1:0])
|
||||
2'b00: data = (data >> 0);
|
||||
2'b01: data = (data >> 8);
|
||||
2'b10: data = (data >> 16);
|
||||
2'b11: data = (data >> 24);
|
||||
endcase
|
||||
2'b00: data = (data >> 0);
|
||||
2'b01: data = (data >> 8);
|
||||
2'b10: data = (data >> 16);
|
||||
2'b11: data = (data >> 24);
|
||||
endcase
|
||||
2: case (addr [1:0])
|
||||
2'b00: data = (data >> 0);
|
||||
2'b10: data = (data >> 16);
|
||||
default: err = True;
|
||||
endcase
|
||||
2'b00: data = (data >> 0);
|
||||
2'b10: data = (data >> 16);
|
||||
default: err = True;
|
||||
endcase
|
||||
4: case (addr [1:0])
|
||||
2'b00: data = (data >> 0);
|
||||
default: err = True;
|
||||
endcase
|
||||
2'b00: data = (data >> 0);
|
||||
default: err = True;
|
||||
endcase
|
||||
default: err = True;
|
||||
endcase
|
||||
return tuple2 (err, data);
|
||||
@@ -176,38 +176,38 @@ endfunction
|
||||
// 64b version
|
||||
|
||||
function Tuple2 #(Bool, // err: misaligned, or bad data_width
|
||||
Bit #(64)) // lane-unadjusted data
|
||||
Bit #(64)) // lane-unadjusted data
|
||||
fn_lane_unadjust_64b (Bit #(64) addr, Bit #(4) dw, Bit #(64) data);
|
||||
|
||||
Bool err = False;
|
||||
|
||||
case (dw)
|
||||
1: case (addr [2:0])
|
||||
3'b000: data = (data >> 0);
|
||||
3'b001: data = (data >> 8);
|
||||
3'b010: data = (data >> 16);
|
||||
3'b011: data = (data >> 24);
|
||||
3'b100: data = (data >> 32);
|
||||
3'b101: data = (data >> 40);
|
||||
3'b110: data = (data >> 48);
|
||||
3'b111: data = (data >> 56);
|
||||
endcase
|
||||
3'b000: data = (data >> 0);
|
||||
3'b001: data = (data >> 8);
|
||||
3'b010: data = (data >> 16);
|
||||
3'b011: data = (data >> 24);
|
||||
3'b100: data = (data >> 32);
|
||||
3'b101: data = (data >> 40);
|
||||
3'b110: data = (data >> 48);
|
||||
3'b111: data = (data >> 56);
|
||||
endcase
|
||||
2: case (addr [2:0])
|
||||
3'b000: data = (data >> 0);
|
||||
3'b010: data = (data >> 16);
|
||||
3'b100: data = (data >> 32);
|
||||
3'b110: data = (data >> 48);
|
||||
default: err = True;
|
||||
endcase
|
||||
3'b000: data = (data >> 0);
|
||||
3'b010: data = (data >> 16);
|
||||
3'b100: data = (data >> 32);
|
||||
3'b110: data = (data >> 48);
|
||||
default: err = True;
|
||||
endcase
|
||||
4: case (addr [2:0])
|
||||
3'b000: data = (data >> 0);
|
||||
3'b100: data = (data >> 32);
|
||||
default: err = True;
|
||||
endcase
|
||||
3'b000: data = (data >> 0);
|
||||
3'b100: data = (data >> 32);
|
||||
default: err = True;
|
||||
endcase
|
||||
8: case (addr [2:0])
|
||||
3'b000: data = (data >> 0);
|
||||
default: err = True;
|
||||
endcase
|
||||
3'b000: data = (data >> 0);
|
||||
default: err = True;
|
||||
endcase
|
||||
default: err = True;
|
||||
endcase
|
||||
return tuple2 (err, data);
|
||||
|
||||
@@ -39,16 +39,16 @@ module mkCreditCounter (CreditCounter_IFC #(w));
|
||||
|
||||
method Action incr;
|
||||
if (crg [0] == maxBound) begin
|
||||
$display ("%0d: ERROR: CreditCounter: overflow", cur_cycle);
|
||||
$finish (1); // Assertion failure
|
||||
$display ("%0d: ERROR: CreditCounter: overflow", cur_cycle);
|
||||
$finish (1); // Assertion failure
|
||||
end
|
||||
crg [0] <= crg [0] + 1;
|
||||
endmethod
|
||||
|
||||
method Action decr () if (crg [1] != 0);
|
||||
if (crg [1] == 0) begin
|
||||
$display ("%0d: ERROR: CreditCounter: underflow", cur_cycle);
|
||||
$finish (1); // Assertion failure
|
||||
$display ("%0d: ERROR: CreditCounter: underflow", cur_cycle);
|
||||
$finish (1); // Assertion failure
|
||||
end
|
||||
crg [1] <= crg [1] - 1;
|
||||
endmethod
|
||||
|
||||
@@ -6,9 +6,9 @@ package Cur_Cycle;
|
||||
// A convenience function to return the current cycle number during BSV simulations
|
||||
|
||||
ActionValue #(Bit #(32)) cur_cycle = actionvalue
|
||||
Bit #(32) t <- $stime;
|
||||
return t / 10;
|
||||
endactionvalue;
|
||||
Bit #(32) t <- $stime;
|
||||
return t / 10;
|
||||
endactionvalue;
|
||||
|
||||
// ================================================================
|
||||
|
||||
|
||||
@@ -26,26 +26,26 @@ endfunction
|
||||
// 'put' is always enabled and just discards its argument.
|
||||
|
||||
Get #(t) getstub = interface Get;
|
||||
method ActionValue #(t) get () if (False);
|
||||
return ?;
|
||||
endmethod
|
||||
endinterface;
|
||||
method ActionValue #(t) get () if (False);
|
||||
return ?;
|
||||
endmethod
|
||||
endinterface;
|
||||
|
||||
Put #(t) putstub = interface Put;
|
||||
method Action put (t x) if (True);
|
||||
noAction;
|
||||
endmethod
|
||||
endinterface;
|
||||
method Action put (t x) if (True);
|
||||
noAction;
|
||||
endmethod
|
||||
endinterface;
|
||||
|
||||
Client #(t1,t2) client_stub = interface Client;
|
||||
interface request = getstub;
|
||||
interface response = putstub;
|
||||
endinterface;
|
||||
interface request = getstub;
|
||||
interface response = putstub;
|
||||
endinterface;
|
||||
|
||||
Server #(t1,t2) server_stub = interface Server;
|
||||
interface request = putstub;
|
||||
interface response = getstub;
|
||||
endinterface;
|
||||
interface request = putstub;
|
||||
interface response = getstub;
|
||||
endinterface;
|
||||
|
||||
// ================================================================
|
||||
// For debugging, a convenience function to display full/empty status of a FIFO
|
||||
@@ -96,30 +96,30 @@ endmodule
|
||||
// dequeue side: never ready
|
||||
|
||||
FIFOF #(t) dummy_FIFOF = interface FIFOF;
|
||||
method Action enq (x) if (False);
|
||||
noAction;
|
||||
endmethod
|
||||
method Action enq (x) if (False);
|
||||
noAction;
|
||||
endmethod
|
||||
|
||||
method notFull;
|
||||
return False;
|
||||
endmethod
|
||||
method notFull;
|
||||
return False;
|
||||
endmethod
|
||||
|
||||
method first () if (False);
|
||||
return ?;
|
||||
endmethod
|
||||
method first () if (False);
|
||||
return ?;
|
||||
endmethod
|
||||
|
||||
method Action deq () if (False);
|
||||
noAction;
|
||||
endmethod
|
||||
method Action deq () if (False);
|
||||
noAction;
|
||||
endmethod
|
||||
|
||||
method notEmpty;
|
||||
return False;
|
||||
endmethod
|
||||
method notEmpty;
|
||||
return False;
|
||||
endmethod
|
||||
|
||||
method Action clear;
|
||||
noAction;
|
||||
endmethod
|
||||
endinterface;
|
||||
method Action clear;
|
||||
noAction;
|
||||
endmethod
|
||||
endinterface;
|
||||
|
||||
// ================================================================
|
||||
|
||||
|
||||
@@ -41,34 +41,34 @@ endtypeclass
|
||||
instance To_FIFOF_IO#(FIFOF#(t), t);
|
||||
function FIFOF_I #(t) to_FIFOF_I (FIFOF #(t) f);
|
||||
return interface FIFOF_I;
|
||||
method enq (x) = f.enq (x);
|
||||
method notFull = f.notFull;
|
||||
endinterface;
|
||||
method enq (x) = f.enq (x);
|
||||
method notFull = f.notFull;
|
||||
endinterface;
|
||||
endfunction
|
||||
|
||||
function FIFOF_O #(t) to_FIFOF_O (FIFOF #(t) f);
|
||||
return interface FIFOF_O;
|
||||
method first = f.first;
|
||||
method deq = f.deq;
|
||||
method notEmpty = f.notEmpty;
|
||||
endinterface;
|
||||
method first = f.first;
|
||||
method deq = f.deq;
|
||||
method notEmpty = f.notEmpty;
|
||||
endinterface;
|
||||
endfunction
|
||||
endinstance
|
||||
|
||||
instance To_FIFOF_IO#(FIFOLevelIfc#(t,n), t);
|
||||
function FIFOF_I #(t) to_FIFOF_I (FIFOLevelIfc #(t,n) f);
|
||||
return interface FIFOF_I;
|
||||
method enq (x) = f.enq (x);
|
||||
method notFull = f.notFull;
|
||||
endinterface;
|
||||
method enq (x) = f.enq (x);
|
||||
method notFull = f.notFull;
|
||||
endinterface;
|
||||
endfunction
|
||||
|
||||
function FIFOF_O #(t) to_FIFOF_O (FIFOLevelIfc #(t,n) f);
|
||||
return interface FIFOF_O;
|
||||
method first = f.first;
|
||||
method deq = f.deq;
|
||||
method notEmpty = f.notEmpty;
|
||||
endinterface;
|
||||
method first = f.first;
|
||||
method deq = f.deq;
|
||||
method notEmpty = f.notEmpty;
|
||||
endinterface;
|
||||
endfunction
|
||||
endinstance
|
||||
|
||||
@@ -78,24 +78,24 @@ endinstance
|
||||
instance ToGet#(FIFOF_O#(t), t);
|
||||
function toGet(ff) = (
|
||||
interface Get;
|
||||
method get();
|
||||
actionvalue
|
||||
ff.deq;
|
||||
return ff.first;
|
||||
endactionvalue
|
||||
endmethod
|
||||
method get();
|
||||
actionvalue
|
||||
ff.deq;
|
||||
return ff.first;
|
||||
endactionvalue
|
||||
endmethod
|
||||
endinterface
|
||||
);
|
||||
);
|
||||
endinstance
|
||||
|
||||
instance ToPut#(FIFOF_I#(t), t);
|
||||
function toPut(ff) = (
|
||||
interface Put;
|
||||
method Action put(x);
|
||||
ff.enq(x);
|
||||
endmethod
|
||||
method Action put(x);
|
||||
ff.enq(x);
|
||||
endmethod
|
||||
endinterface
|
||||
);
|
||||
);
|
||||
endinstance
|
||||
|
||||
// ================================================================
|
||||
@@ -107,8 +107,8 @@ endinstance
|
||||
instance Connectable #(FIFOF_O #(t), FIFOF_I #(t));
|
||||
module mkConnection #(FIFOF_O #(t) fo, FIFOF_I #(t) fi) (Empty);
|
||||
rule rl_connect;
|
||||
fi.enq (fo.first);
|
||||
fo.deq;
|
||||
fi.enq (fo.first);
|
||||
fo.deq;
|
||||
endrule
|
||||
endmodule
|
||||
endinstance
|
||||
@@ -128,8 +128,8 @@ endinstance
|
||||
instance Connectable #(FIFOF_O #(t), FIFOF #(t));
|
||||
module mkConnection #(FIFOF_O #(t) fo, FIFOF #(t) fi) (Empty);
|
||||
rule rl_connect;
|
||||
fi.enq (fo.first);
|
||||
fo.deq;
|
||||
fi.enq (fo.first);
|
||||
fo.deq;
|
||||
endrule
|
||||
endmodule
|
||||
endinstance
|
||||
@@ -140,8 +140,8 @@ endinstance
|
||||
instance Connectable #(FIFOF #(t), FIFOF_I #(t));
|
||||
module mkConnection #(FIFOF #(t) fo, FIFOF_I #(t) fi) (Empty);
|
||||
rule rl_connect;
|
||||
fi.enq (fo.first);
|
||||
fo.deq;
|
||||
fi.enq (fo.first);
|
||||
fo.deq;
|
||||
endrule
|
||||
endmodule
|
||||
endinstance
|
||||
@@ -162,29 +162,29 @@ endfunction
|
||||
// dummy_FIFO_I that never accepts anything (always "full")
|
||||
|
||||
FIFOF_I #(t) dummy_FIFOF_I = interface FIFOF_I;
|
||||
method Action enq (x) if (False);
|
||||
noAction;
|
||||
endmethod
|
||||
method notFull;
|
||||
return False;
|
||||
endmethod
|
||||
endinterface;
|
||||
method Action enq (x) if (False);
|
||||
noAction;
|
||||
endmethod
|
||||
method notFull;
|
||||
return False;
|
||||
endmethod
|
||||
endinterface;
|
||||
|
||||
// Dummy FIFO_O that never yields anything (always "empty")
|
||||
|
||||
FIFOF_O #(t) dummy_FIFOF_O = interface FIFOF_O;
|
||||
method first () if (False);
|
||||
return ?;
|
||||
endmethod
|
||||
method first () if (False);
|
||||
return ?;
|
||||
endmethod
|
||||
|
||||
method Action deq () if (False);
|
||||
noAction;
|
||||
endmethod
|
||||
method Action deq () if (False);
|
||||
noAction;
|
||||
endmethod
|
||||
|
||||
method notEmpty;
|
||||
return False;
|
||||
endmethod
|
||||
endinterface;
|
||||
method notEmpty;
|
||||
return False;
|
||||
endmethod
|
||||
endinterface;
|
||||
|
||||
|
||||
// ================================================================
|
||||
|
||||
@@ -174,9 +174,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LWSP (MISA misa, Bit #(2) xl, Instr
|
||||
Bit #(8) offset = { imm_at_6_2 [1:0], imm_at_12, imm_at_6_2 [4:2], 2'b0};
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (rd != 0)
|
||||
&& (funct3 == funct3_C_LWSP));
|
||||
&& (op == opcode_C2)
|
||||
&& (rd != 0)
|
||||
&& (funct3 == funct3_C_LWSP));
|
||||
|
||||
RegName rs1 = reg_sp;
|
||||
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LW, rd, op_LOAD);
|
||||
@@ -194,11 +194,11 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LDSP (MISA misa, Bit #(2) xl, Instr
|
||||
Bit #(9) offset = { imm_at_6_2 [2:0], imm_at_12, imm_at_6_2 [4:3], 3'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (rd != 0)
|
||||
&& (funct3 == funct3_C_LDSP)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
&& (op == opcode_C2)
|
||||
&& (rd != 0)
|
||||
&& (funct3 == funct3_C_LDSP)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
|
||||
RegName rs1 = reg_sp;
|
||||
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LD, rd, op_LOAD);
|
||||
@@ -217,10 +217,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LQSP (MISA misa, Bit #(2) xl, Instr
|
||||
Bit #(10) offset = { imm_at_6_2 [3:0], imm_at_12, imm_at_6_2 [4], 4'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (rd != 0)
|
||||
&& (funct3 == funct3_C_LQSP)
|
||||
&& (xl == misa_mxl_128));
|
||||
&& (op == opcode_C2)
|
||||
&& (rd != 0)
|
||||
&& (funct3 == funct3_C_LQSP)
|
||||
&& (xl == misa_mxl_128));
|
||||
|
||||
RegName rs1 = reg_sp;
|
||||
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LQ, rd, op_LOAD);
|
||||
@@ -239,10 +239,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FLWSP (MISA misa, Bit #(2) xl, Inst
|
||||
Bit #(8) offset = { imm_at_6_2 [1:0], imm_at_12, imm_at_6_2 [4:2], 2'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (rd != 0)
|
||||
&& (funct3 == funct3_C_FLWSP)
|
||||
&& (misa.f == 1'b1));
|
||||
&& (op == opcode_C2)
|
||||
&& (rd != 0)
|
||||
&& (funct3 == funct3_C_FLWSP)
|
||||
&& (misa.f == 1'b1));
|
||||
|
||||
RegName rs1 = reg_sp;
|
||||
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_FLW, rd, op_LOAD_FP);
|
||||
@@ -261,12 +261,12 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FLDSP (MISA misa, Bit #(2) xl, Inst
|
||||
Bit #(9) offset = { imm_at_6_2 [2:0], imm_at_12, imm_at_6_2 [4:3], 3'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (rd != 0)
|
||||
&& (funct3 == funct3_C_FLDSP)
|
||||
&& (misa.d == 1'b1)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
&& (op == opcode_C2)
|
||||
&& (rd != 0)
|
||||
&& (funct3 == funct3_C_FLDSP)
|
||||
&& (misa.d == 1'b1)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
|
||||
RegName rs1 = reg_sp;
|
||||
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_FLD, rd, op_LOAD_FP);
|
||||
@@ -287,8 +287,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SWSP (MISA misa, Bit #(2) xl, Inst
|
||||
Bit #(8) offset = { imm_at_12_7 [1:0], imm_at_12_7 [5:2], 2'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (funct3 == funct3_C_SWSP));
|
||||
&& (op == opcode_C2)
|
||||
&& (funct3 == funct3_C_SWSP));
|
||||
|
||||
RegName rs1 = reg_sp;
|
||||
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SW, op_STORE);
|
||||
@@ -306,10 +306,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SDSP (MISA misa, Bit #(2) xl, Inst
|
||||
Bit #(9) offset = { imm_at_12_7 [2:0], imm_at_12_7 [5:3], 3'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (funct3 == funct3_C_SDSP)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
&& (op == opcode_C2)
|
||||
&& (funct3 == funct3_C_SDSP)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
|
||||
RegName rs1 = reg_sp;
|
||||
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SD, op_STORE);
|
||||
@@ -328,9 +328,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SQSP (MISA misa, Bit #(2) xl, Inst
|
||||
Bit #(10) offset = { imm_at_12_7 [3:0], imm_at_12_7 [5:4], 4'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (funct3 == funct3_C_SQSP)
|
||||
&& (xl == misa_mxl_128));
|
||||
&& (op == opcode_C2)
|
||||
&& (funct3 == funct3_C_SQSP)
|
||||
&& (xl == misa_mxl_128));
|
||||
|
||||
RegName rs1 = reg_sp;
|
||||
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SQ, op_STORE);
|
||||
@@ -349,8 +349,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FSWSP (MISA misa, Bit #(2) xl, Ins
|
||||
Bit #(8) offset = { imm_at_12_7 [1:0], imm_at_12_7 [5:2], 2'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (funct3 == funct3_C_FSWSP));
|
||||
&& (op == opcode_C2)
|
||||
&& (funct3 == funct3_C_FSWSP));
|
||||
|
||||
RegName rs1 = reg_sp;
|
||||
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_FSW, op_STORE_FP);
|
||||
@@ -369,10 +369,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FSDSP (MISA misa, Bit #(2) xl, Ins
|
||||
Bit #(9) offset = { imm_at_12_7 [2:0], imm_at_12_7 [5:3], 3'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (funct3 == funct3_C_FSDSP)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
&& (op == opcode_C2)
|
||||
&& (funct3 == funct3_C_FSDSP)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
|
||||
RegName rs1 = reg_sp;
|
||||
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_FSD, op_STORE_FP);
|
||||
@@ -393,8 +393,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LW (MISA misa, Bit #(2) xl, Instr
|
||||
Bit #(7) offset = { imm_at_6_5 [0], imm_at_12_10, imm_at_6_5 [1], 2'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_LW));
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_LW));
|
||||
|
||||
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LW, rd, op_LOAD);
|
||||
|
||||
@@ -411,10 +411,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LD (MISA misa, Bit #(2) xl, Instr
|
||||
Bit #(8) offset = { imm_at_6_5, imm_at_12_10, 3'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_LD)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_LD)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
|
||||
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LD, rd, op_LOAD);
|
||||
|
||||
@@ -432,9 +432,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LQ (MISA misa, Bit #(2) xl, Instr
|
||||
Bit #(9) offset = { imm_at_12_10 [0], imm_at_6_5, imm_at_12_10 [2], imm_at_12_10 [1], 4'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_LQ)
|
||||
&& (xl == misa_mxl_128));
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_LQ)
|
||||
&& (xl == misa_mxl_128));
|
||||
|
||||
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_LQ, rd, op_LOAD);
|
||||
|
||||
@@ -452,8 +452,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FLW (MISA misa, Bit #(2) xl, Inst
|
||||
Bit #(7) offset = { imm_at_6_5 [0], imm_at_12_10, imm_at_6_5 [1], 2'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_FLW));
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_FLW));
|
||||
|
||||
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_FLW, rd, op_LOAD_FP);
|
||||
|
||||
@@ -471,10 +471,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FLD (MISA misa, Bit #(2) xl, Inst
|
||||
Bit #(8) offset = { imm_at_6_5, imm_at_12_10, 3'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_FLD)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_FLD)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
|
||||
let instr = mkInstr_I_type (zeroExtend (offset), rs1, f3_FLD, rd, op_LOAD_FP);
|
||||
|
||||
@@ -494,8 +494,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SW (MISA misa, Bit #(2) xl, Instr
|
||||
Bit #(7) offset = { imm_at_6_5 [0], imm_at_12_10, imm_at_6_5 [1], 2'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_SW));
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_SW));
|
||||
|
||||
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SW, op_STORE);
|
||||
|
||||
@@ -512,8 +512,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SD (MISA misa, Bit #(2) xl, Instr
|
||||
Bit #(8) offset = { imm_at_6_5, imm_at_12_10, 3'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_SD));
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_SD));
|
||||
|
||||
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SD, op_STORE);
|
||||
|
||||
@@ -531,8 +531,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SQ (MISA misa, Bit #(2) xl, Instr
|
||||
Bit #(9) offset = { imm_at_12_10 [0], imm_at_6_5, imm_at_12_10 [2], imm_at_12_10 [1], 4'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_SQ));
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_SQ));
|
||||
|
||||
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_SQ, op_STORE);
|
||||
|
||||
@@ -550,8 +550,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FSW (MISA misa, Bit #(2) xl, Inst
|
||||
Bit #(7) offset = { imm_at_6_5 [0], imm_at_12_10, imm_at_6_5 [1], 2'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_FSW));
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_FSW));
|
||||
|
||||
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_FSW, op_STORE_FP);
|
||||
|
||||
@@ -569,8 +569,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_FSD (MISA misa, Bit #(2) xl, Inst
|
||||
Bit #(8) offset = { imm_at_6_5, imm_at_12_10, 3'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_FSD));
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_FSD));
|
||||
|
||||
let instr = mkInstr_S_type (zeroExtend (offset), rs2, rs1, f3_FSD, op_STORE_FP);
|
||||
|
||||
@@ -589,18 +589,18 @@ function Tuple2 #(Bool, Instr) fv_decode_C_J (MISA misa, Bit #(2) xl, Instr_
|
||||
// Instr fields: CJ-type
|
||||
match { .funct3, .imm_at_12_2, .op } = fv_ifields_CJ_type (instr_C);
|
||||
Bit #(12) offset = {imm_at_12_2 [10],
|
||||
imm_at_12_2 [6],
|
||||
imm_at_12_2 [8:7],
|
||||
imm_at_12_2 [4],
|
||||
imm_at_12_2 [5],
|
||||
imm_at_12_2 [0],
|
||||
imm_at_12_2 [9],
|
||||
imm_at_12_2 [3:1],
|
||||
1'b0};
|
||||
imm_at_12_2 [6],
|
||||
imm_at_12_2 [8:7],
|
||||
imm_at_12_2 [4],
|
||||
imm_at_12_2 [5],
|
||||
imm_at_12_2 [0],
|
||||
imm_at_12_2 [9],
|
||||
imm_at_12_2 [3:1],
|
||||
1'b0};
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_J));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_J));
|
||||
|
||||
RegName rd = reg_zero;
|
||||
Bit #(21) imm21 = signExtend (offset);
|
||||
@@ -616,19 +616,19 @@ function Tuple2 #(Bool, Instr) fv_decode_C_JAL (MISA misa, Bit #(2) xl, Inst
|
||||
// Instr fields: CJ-type
|
||||
match { .funct3, .imm_at_12_2, .op } = fv_ifields_CJ_type (instr_C);
|
||||
Bit #(12) offset = {imm_at_12_2 [10],
|
||||
imm_at_12_2 [6],
|
||||
imm_at_12_2 [8:7],
|
||||
imm_at_12_2 [4],
|
||||
imm_at_12_2 [5],
|
||||
imm_at_12_2 [0],
|
||||
imm_at_12_2 [9],
|
||||
imm_at_12_2 [3:1],
|
||||
1'b0};
|
||||
imm_at_12_2 [6],
|
||||
imm_at_12_2 [8:7],
|
||||
imm_at_12_2 [4],
|
||||
imm_at_12_2 [5],
|
||||
imm_at_12_2 [0],
|
||||
imm_at_12_2 [9],
|
||||
imm_at_12_2 [3:1],
|
||||
1'b0};
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_JAL)
|
||||
&& (xl == misa_mxl_32));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_JAL)
|
||||
&& (xl == misa_mxl_32));
|
||||
|
||||
RegName rd = reg_ra;
|
||||
Bit #(21) imm21 = signExtend (offset);
|
||||
@@ -645,10 +645,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_JR (MISA misa, Bit #(2) xl, Instr
|
||||
match { .funct4, .rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (funct4 == funct4_C_JR)
|
||||
&& (rs1 != 0)
|
||||
&& (rs2 == 0));
|
||||
&& (op == opcode_C2)
|
||||
&& (funct4 == funct4_C_JR)
|
||||
&& (rs1 != 0)
|
||||
&& (rs2 == 0));
|
||||
|
||||
RegName rd = reg_zero;
|
||||
Bit #(12) imm12 = 0;
|
||||
@@ -664,10 +664,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_JALR (MISA misa, Bit #(2) xl, Ins
|
||||
match { .funct4, .rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (funct4 == funct4_C_JALR)
|
||||
&& (rs1 != 0)
|
||||
&& (rs2 == 0));
|
||||
&& (op == opcode_C2)
|
||||
&& (funct4 == funct4_C_JALR)
|
||||
&& (rs1 != 0)
|
||||
&& (rs2 == 0));
|
||||
|
||||
RegName rd = reg_ra;
|
||||
Bit #(12) imm12 = 0;
|
||||
@@ -685,8 +685,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_BEQZ (MISA misa, Bit #(2) xl, Ins
|
||||
Bit #(9) offset = { imm_at_12_10 [2], imm_at_6_2 [4:3], imm_at_6_2 [0], imm_at_12_10 [1:0], imm_at_6_2 [2:1], 1'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_BEQZ));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_BEQZ));
|
||||
|
||||
RegName rs2 = reg_zero;
|
||||
Bit #(13) imm13 = signExtend (offset);
|
||||
@@ -704,8 +704,8 @@ function Tuple2 #(Bool, Instr) fv_decode_C_BNEZ (MISA misa, Bit #(2) xl, Ins
|
||||
Bit #(9) offset = { imm_at_12_10 [2], imm_at_6_2 [4:3], imm_at_6_2 [0], imm_at_12_10 [1:0], imm_at_6_2 [2:1], 1'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_BNEZ));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_BNEZ));
|
||||
|
||||
RegName rs2 = reg_zero;
|
||||
Bit #(13) imm13 = signExtend (offset);
|
||||
@@ -726,9 +726,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LI (MISA misa, Bit #(2) xl, Instr
|
||||
Bit #(6) imm6 = { imm_at_12, imm_at_6_2 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_LI)
|
||||
&& (rd != 0));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_LI)
|
||||
&& (rd != 0));
|
||||
|
||||
RegName rs1 = reg_zero;
|
||||
Bit #(12) imm12 = signExtend (imm6);
|
||||
@@ -746,11 +746,11 @@ function Tuple2 #(Bool, Instr) fv_decode_C_LUI (MISA misa, Bit #(2) xl, Inst
|
||||
Bit #(6) nzimm6 = { imm_at_12, imm_at_6_2 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_LUI)
|
||||
&& (rd != 0)
|
||||
&& (rd != 2)
|
||||
&& (nzimm6 != 0));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_LUI)
|
||||
&& (rd != 0)
|
||||
&& (rd != 2)
|
||||
&& (nzimm6 != 0));
|
||||
|
||||
Bit #(20) imm20 = signExtend (nzimm6);
|
||||
let instr = mkInstr_U_type (imm20, rd, op_LUI);
|
||||
@@ -770,10 +770,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDI (MISA misa, Bit #(2) xl, Ins
|
||||
Bit #(6) nzimm6 = { imm_at_12, imm_at_6_2 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_ADDI)
|
||||
&& (rd_rs1 != 0)
|
||||
&& (nzimm6 != 0));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_ADDI)
|
||||
&& (rd_rs1 != 0)
|
||||
&& (nzimm6 != 0));
|
||||
|
||||
Bit #(12) imm12 = signExtend (nzimm6);
|
||||
let instr = mkInstr_I_type (imm12, rd_rs1, f3_ADDI, rd_rs1, op_OP_IMM);
|
||||
@@ -790,10 +790,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_NOP (MISA misa, Bit #(2) xl, Inst
|
||||
Bit #(6) nzimm6 = { imm_at_12, imm_at_6_2 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_NOP)
|
||||
&& (rd_rs1 == 0)
|
||||
&& (nzimm6 == 0));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_NOP)
|
||||
&& (rd_rs1 == 0)
|
||||
&& (nzimm6 == 0));
|
||||
|
||||
Bit #(12) imm12 = signExtend (nzimm6);
|
||||
let instr = mkInstr_I_type (imm12, rd_rs1, f3_ADDI, rd_rs1, op_OP_IMM);
|
||||
@@ -810,11 +810,11 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDIW (MISA misa, Bit #(2) xl, In
|
||||
Bit #(6) imm6 = { imm_at_12, imm_at_6_2 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_ADDIW)
|
||||
&& (rd_rs1 != 0)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_ADDIW)
|
||||
&& (rd_rs1 != 0)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
|
||||
Bit #(12) imm12 = signExtend (imm6);
|
||||
let instr = mkInstr_I_type (imm12, rd_rs1, f3_ADDIW, rd_rs1, op_OP_IMM_32);
|
||||
@@ -831,10 +831,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDI16SP (MISA misa, Bit #(2) xl,
|
||||
Bit #(10) nzimm10 = { imm_at_12, imm_at_6_2 [2:1], imm_at_6_2 [3], imm_at_6_2 [0], imm_at_6_2 [4], 4'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_ADDI16SP)
|
||||
&& (rd_rs1 == reg_sp)
|
||||
&& (nzimm10 != 0));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_ADDI16SP)
|
||||
&& (rd_rs1 == reg_sp)
|
||||
&& (nzimm10 != 0));
|
||||
|
||||
Bit #(12) imm12 = signExtend (nzimm10);
|
||||
let instr = mkInstr_I_type (imm12, rd_rs1, f3_ADDI, rd_rs1, op_OP_IMM);
|
||||
@@ -851,9 +851,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDI4SPN (MISA misa, Bit #(2) xl,
|
||||
Bit #(10) nzimm10 = { imm_at_12_5 [5:2], imm_at_12_5 [7:6], imm_at_12_5 [0], imm_at_12_5 [1], 2'b0 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_ADDI4SPN)
|
||||
&& (nzimm10 != 0));
|
||||
&& (op == opcode_C0)
|
||||
&& (funct3 == funct3_C_ADDI4SPN)
|
||||
&& (nzimm10 != 0));
|
||||
|
||||
RegName rs1 = reg_sp;
|
||||
Bit #(12) imm12 = zeroExtend (nzimm10);
|
||||
@@ -871,15 +871,15 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SLLI (MISA misa, Bit #(2) xl, Ins
|
||||
Bit #(6) shamt6 = { imm_at_12, imm_at_6_2 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (funct3 == funct3_C_SLLI)
|
||||
&& (rd_rs1 != 0)
|
||||
&& (op == opcode_C2)
|
||||
&& (funct3 == funct3_C_SLLI)
|
||||
&& (rd_rs1 != 0)
|
||||
&& (shamt6 != 0)
|
||||
&& ((xl == misa_mxl_32) ? (imm_at_12 == 0) : True));
|
||||
&& ((xl == misa_mxl_32) ? (imm_at_12 == 0) : True));
|
||||
|
||||
Bit #(12) imm12 = ( (xl == misa_mxl_32)
|
||||
? { msbs7_SLLI, imm_at_6_2 }
|
||||
: { msbs6_SLLI, shamt6 } );
|
||||
? { msbs7_SLLI, imm_at_6_2 }
|
||||
: { msbs6_SLLI, shamt6 } );
|
||||
let instr = mkInstr_I_type (imm12, rd_rs1, f3_SLLI, rd_rs1, op_OP_IMM);
|
||||
|
||||
return tuple2 (is_legal, instr);
|
||||
@@ -896,16 +896,16 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SRLI (MISA misa, Bit #(2) xl, Ins
|
||||
Bit #(6) shamt6 = { shamt6_5, imm_at_6_2 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_SRLI)
|
||||
&& (funct2 == funct2_C_SRLI)
|
||||
&& (rd_rs1 != 0)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_SRLI)
|
||||
&& (funct2 == funct2_C_SRLI)
|
||||
&& (rd_rs1 != 0)
|
||||
&& (shamt6 != 0)
|
||||
&& ((xl == misa_mxl_32) ? (shamt6_5 == 0) : True));
|
||||
&& ((xl == misa_mxl_32) ? (shamt6_5 == 0) : True));
|
||||
|
||||
Bit #(12) imm12 = ( (xl == misa_mxl_32)
|
||||
? { msbs7_SRLI, imm_at_6_2 }
|
||||
: { msbs6_SRLI, shamt6 } );
|
||||
? { msbs7_SRLI, imm_at_6_2 }
|
||||
: { msbs6_SRLI, shamt6 } );
|
||||
let instr = mkInstr_I_type (imm12, rd_rs1, f3_SRLI, rd_rs1, op_OP_IMM);
|
||||
|
||||
return tuple2 (is_legal, instr);
|
||||
@@ -922,16 +922,16 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SRAI (MISA misa, Bit #(2) xl, Ins
|
||||
Bit #(6) shamt6 = { shamt6_5, imm_at_6_2 };
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_SRAI)
|
||||
&& (funct2 == funct2_C_SRAI)
|
||||
&& (rd_rs1 != 0)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_SRAI)
|
||||
&& (funct2 == funct2_C_SRAI)
|
||||
&& (rd_rs1 != 0)
|
||||
&& (shamt6 != 0)
|
||||
&& ((xl == misa_mxl_32) ? (shamt6_5 == 0) : True));
|
||||
&& ((xl == misa_mxl_32) ? (shamt6_5 == 0) : True));
|
||||
|
||||
Bit #(12) imm12 = ( (xl == misa_mxl_32)
|
||||
? { msbs7_SRAI, imm_at_6_2 }
|
||||
: { msbs6_SRAI, shamt6 } );
|
||||
? { msbs7_SRAI, imm_at_6_2 }
|
||||
: { msbs6_SRAI, shamt6 } );
|
||||
let instr = mkInstr_I_type (imm12, rd_rs1, f3_SRAI, rd_rs1, op_OP_IMM);
|
||||
|
||||
return tuple2 (is_legal, instr);
|
||||
@@ -948,9 +948,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ANDI (MISA misa, Bit #(2) xl, Ins
|
||||
Bit #(2) funct2 = imm_at_12_10 [1:0];
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_ANDI)
|
||||
&& (funct2 == funct2_C_ANDI));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct3 == funct3_C_ANDI)
|
||||
&& (funct2 == funct2_C_ANDI));
|
||||
|
||||
Bit #(12) imm12 = signExtend (imm6);
|
||||
let instr = mkInstr_I_type (imm12, rd_rs1, f3_ANDI, rd_rs1, op_OP_IMM);
|
||||
@@ -968,10 +968,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_MV (MISA misa, Bit #(2) xl, Instr
|
||||
match { .funct4, .rd_rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (funct4 == funct4_C_MV)
|
||||
&& (rd_rs1 != 0)
|
||||
&& (rs2 != 0));
|
||||
&& (op == opcode_C2)
|
||||
&& (funct4 == funct4_C_MV)
|
||||
&& (rd_rs1 != 0)
|
||||
&& (rs2 != 0));
|
||||
|
||||
RegName rs1 = reg_zero;
|
||||
let instr = mkInstr_R_type (funct7_ADD, rs2, rs1, funct3_ADD, rd_rs1, op_OP);
|
||||
@@ -986,10 +986,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADD (MISA misa, Bit #(2) xl, Inst
|
||||
match { .funct4, .rd_rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (funct4 == funct4_C_ADD)
|
||||
&& (rd_rs1 != 0)
|
||||
&& (rs2 != 0));
|
||||
&& (op == opcode_C2)
|
||||
&& (funct4 == funct4_C_ADD)
|
||||
&& (rd_rs1 != 0)
|
||||
&& (rs2 != 0));
|
||||
|
||||
let instr = mkInstr_R_type (funct7_ADD, rs2, rd_rs1, funct3_ADD, rd_rs1, op_OP);
|
||||
|
||||
@@ -1004,9 +1004,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_AND (MISA misa, Bit #(2) xl, Inst
|
||||
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct6 == funct6_C_AND)
|
||||
&& (funct2 == funct2_C_AND));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct6 == funct6_C_AND)
|
||||
&& (funct2 == funct2_C_AND));
|
||||
|
||||
let instr = mkInstr_R_type (funct7_AND, rs2, rd_rs1, funct3_AND, rd_rs1, op_OP);
|
||||
|
||||
@@ -1021,9 +1021,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_OR (MISA misa, Bit #(2) xl, Instr
|
||||
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct6 == funct6_C_OR)
|
||||
&& (funct2 == funct2_C_OR));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct6 == funct6_C_OR)
|
||||
&& (funct2 == funct2_C_OR));
|
||||
|
||||
let instr = mkInstr_R_type (funct7_OR, rs2, rd_rs1, funct3_OR, rd_rs1, op_OP);
|
||||
|
||||
@@ -1038,9 +1038,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_XOR (MISA misa, Bit #(2) xl, Inst
|
||||
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct6 == funct6_C_XOR)
|
||||
&& (funct2 == funct2_C_XOR));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct6 == funct6_C_XOR)
|
||||
&& (funct2 == funct2_C_XOR));
|
||||
|
||||
let instr = mkInstr_R_type (funct7_XOR, rs2, rd_rs1, funct3_XOR, rd_rs1, op_OP);
|
||||
|
||||
@@ -1055,9 +1055,9 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SUB (MISA misa, Bit #(2) xl, Inst
|
||||
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct6 == funct6_C_SUB)
|
||||
&& (funct2 == funct2_C_SUB));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct6 == funct6_C_SUB)
|
||||
&& (funct2 == funct2_C_SUB));
|
||||
|
||||
let instr = mkInstr_R_type (funct7_SUB, rs2, rd_rs1, funct3_SUB, rd_rs1, op_OP);
|
||||
|
||||
@@ -1072,11 +1072,11 @@ function Tuple2 #(Bool, Instr) fv_decode_C_ADDW (MISA misa, Bit #(2) xl, Ins
|
||||
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct6 == funct6_C_ADDW)
|
||||
&& (funct2 == funct2_C_ADDW)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct6 == funct6_C_ADDW)
|
||||
&& (funct2 == funct2_C_ADDW)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
|
||||
let instr = mkInstr_R_type (funct7_ADDW, rs2, rd_rs1, funct3_ADDW, rd_rs1, op_OP_32);
|
||||
|
||||
@@ -1091,11 +1091,11 @@ function Tuple2 #(Bool, Instr) fv_decode_C_SUBW (MISA misa, Bit #(2) xl, Ins
|
||||
match { .funct6, .rd_rs1, .funct2, .rs2, .op } = fv_ifields_CA_type (instr_C);
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C1)
|
||||
&& (funct6 == funct6_C_SUBW)
|
||||
&& (funct2 == funct2_C_SUBW)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
&& (op == opcode_C1)
|
||||
&& (funct6 == funct6_C_SUBW)
|
||||
&& (funct2 == funct2_C_SUBW)
|
||||
&& ( (xl == misa_mxl_64)
|
||||
|| (xl == misa_mxl_128)));
|
||||
|
||||
let instr = mkInstr_R_type (funct7_SUBW, rs2, rd_rs1, funct3_SUBW, rd_rs1, op_OP_32);
|
||||
|
||||
@@ -1113,10 +1113,10 @@ function Tuple2 #(Bool, Instr) fv_decode_C_EBREAK (MISA misa, Bit #(2) xl, I
|
||||
match { .funct4, .rd_rs1, .rs2, .op } = fv_ifields_CR_type (instr_C);
|
||||
|
||||
Bool is_legal = ((misa.c == 1'b1)
|
||||
&& (op == opcode_C2)
|
||||
&& (funct4 == funct4_C_EBREAK)
|
||||
&& (rd_rs1 == 0)
|
||||
&& (rs2 == 0));
|
||||
&& (op == opcode_C2)
|
||||
&& (funct4 == funct4_C_EBREAK)
|
||||
&& (rd_rs1 == 0)
|
||||
&& (rs2 == 0));
|
||||
|
||||
Bit #(12) imm12 = f12_EBREAK;
|
||||
let instr = mkInstr_I_type (imm12, rd_rs1, f3_PRIV, rd_rs1, op_SYSTEM);
|
||||
|
||||
@@ -421,7 +421,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
method rob_getPC = rob.getOrigPC[valueof(AluExeNum)].get; // last getPC port
|
||||
method rob_setExecuted_doFinishMem = rob.setExecuted_doFinishMem;
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
method rob_setExecuted_doFinishMem_RegData = rob.setExecuted_doFinishMem_RegData;
|
||||
method rob_setExecuted_doFinishMem_RegData = rob.setExecuted_doFinishMem_RegData;
|
||||
`endif
|
||||
method rob_setExecuted_deqLSQ = rob.setExecuted_deqLSQ;
|
||||
method isMMIOAddr = mmio.isMMIOAddr;
|
||||
@@ -581,38 +581,38 @@ module mkCore#(CoreId coreId)(Core);
|
||||
method tlbNoPendingReq = iTlb.noPendingReq && dTlb.noPendingReq;
|
||||
|
||||
method setFlushTlbs;
|
||||
action
|
||||
flush_tlbs <= True;
|
||||
action
|
||||
flush_tlbs <= True;
|
||||
// $display ("%0d: %m.commitInput.setFlushTlbs", cur_cycle);
|
||||
endaction
|
||||
endaction
|
||||
endmethod
|
||||
|
||||
method setUpdateVMInfo;
|
||||
action
|
||||
update_vm_info <= True;
|
||||
action
|
||||
update_vm_info <= True;
|
||||
// $display ("%0d: %m.commitInput.setUpdateVMInfo", cur_cycle);
|
||||
endaction
|
||||
endaction
|
||||
endmethod
|
||||
|
||||
method setFlushReservation;
|
||||
action
|
||||
flush_reservation <= True;
|
||||
action
|
||||
flush_reservation <= True;
|
||||
// $display ("%0d: %m.commitInput.setFlushReservation", cur_cycle);
|
||||
endaction
|
||||
endaction
|
||||
endmethod
|
||||
|
||||
method setFlushBrPred;
|
||||
action
|
||||
flush_brpred <= True;
|
||||
action
|
||||
flush_brpred <= True;
|
||||
// $display ("%0d: %m.commitInput.setFlushBrPred", cur_cycle);
|
||||
endaction
|
||||
endaction
|
||||
endmethod
|
||||
|
||||
method setFlushCaches;
|
||||
action
|
||||
flush_caches <= True;
|
||||
action
|
||||
flush_caches <= True;
|
||||
// $display ("%0d: %m.commitInput.setFlushCaches", cur_cycle);
|
||||
endaction
|
||||
endaction
|
||||
endmethod
|
||||
|
||||
method setReconcileI = reconcile_i._write(True);
|
||||
@@ -674,13 +674,13 @@ module mkCore#(CoreId coreId)(Core);
|
||||
if (flush_reservation) begin
|
||||
flush_reservation <= False;
|
||||
dMem.resetLinkAddr;
|
||||
// $display ("%0d: %m.rule prepareCachesAndTlbs: flushing reservation", cur_cycle);
|
||||
// $display ("%0d: %m.rule prepareCachesAndTlbs: flushing reservation", cur_cycle);
|
||||
end
|
||||
if (flush_tlbs) begin
|
||||
flush_tlbs <= False;
|
||||
iTlb.flush;
|
||||
dTlb.flush;
|
||||
// $display ("%0d: %m.rule prepareCachesAndTlbs: flushing iTlb and dTlb", cur_cycle);
|
||||
// $display ("%0d: %m.rule prepareCachesAndTlbs: flushing iTlb and dTlb", cur_cycle);
|
||||
end
|
||||
if (update_vm_info) begin
|
||||
update_vm_info <= False;
|
||||
@@ -689,7 +689,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
iTlb.updateVMInfo(vmI);
|
||||
dTlb.updateVMInfo(vmD);
|
||||
l2Tlb.updateVMInfo(vmI, vmD);
|
||||
// $display ("%0d: %m.rule prepareCachesAndTlbs: updating VMInfo", cur_cycle);
|
||||
// $display ("%0d: %m.rule prepareCachesAndTlbs: updating VMInfo", cur_cycle);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -789,11 +789,11 @@ module mkCore#(CoreId coreId)(Core);
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
if (commitStage.is_debug_halted) begin
|
||||
started <= False;
|
||||
rg_core_run_state <= CORE_HALTING;
|
||||
if (verbosity >= 1)
|
||||
$display ("%0d: %m.rule readyToFetch: halting for debug mode", cur_cycle);
|
||||
end
|
||||
started <= False;
|
||||
rg_core_run_state <= CORE_HALTING;
|
||||
if (verbosity >= 1)
|
||||
$display ("%0d: %m.rule readyToFetch: halting for debug mode", cur_cycle);
|
||||
end
|
||||
`endif
|
||||
endrule
|
||||
|
||||
@@ -1067,15 +1067,15 @@ module mkCore#(CoreId coreId)(Core);
|
||||
FIFOF #(DM_CPU_Rsp #(64)) f_gpr_rsps <- mkFIFOF1;
|
||||
|
||||
rule rl_debug_gpr_read ( (rg_core_run_state == CORE_HALTED)
|
||||
&& f_gpr_reqs.notEmpty
|
||||
&& (! f_gpr_reqs.first.write));
|
||||
&& f_gpr_reqs.notEmpty
|
||||
&& (! f_gpr_reqs.first.write));
|
||||
let req <- pop (f_gpr_reqs);
|
||||
Bit #(5) regnum = req.address;
|
||||
|
||||
let arch_regs = ArchRegs {src1: tagged Valid (tagged Gpr regnum),
|
||||
src2: tagged Invalid,
|
||||
src3: tagged Invalid,
|
||||
dst: tagged Invalid};
|
||||
src2: tagged Invalid,
|
||||
src3: tagged Invalid,
|
||||
dst: tagged Invalid};
|
||||
let rename_result = regRenamingTable.rename[0].getRename (arch_regs);
|
||||
let phy_rindx = fromMaybe (?, rename_result.phy_regs.src1);
|
||||
let data_out = rf.read [debuggerPort].rd1 (phy_rindx);
|
||||
@@ -1084,20 +1084,20 @@ module mkCore#(CoreId coreId)(Core);
|
||||
f_gpr_rsps.enq (rsp);
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_read_gpr: reg %0d => 0x%0h", cur_cycle, regnum, data_out);
|
||||
$display ("%0d: %m.rl_debug_read_gpr: reg %0d => 0x%0h", cur_cycle, regnum, data_out);
|
||||
endrule
|
||||
|
||||
rule rl_debug_gpr_write ( (rg_core_run_state == CORE_HALTED)
|
||||
&& f_gpr_reqs.notEmpty
|
||||
&& f_gpr_reqs.first.write);
|
||||
&& f_gpr_reqs.notEmpty
|
||||
&& f_gpr_reqs.first.write);
|
||||
let req <- pop (f_gpr_reqs);
|
||||
Bit #(5) regnum = req.address;
|
||||
let data_in = req.data;
|
||||
|
||||
let arch_regs = ArchRegs {src1: tagged Valid (tagged Gpr regnum),
|
||||
src2: tagged Invalid,
|
||||
src3: tagged Invalid,
|
||||
dst: tagged Invalid};
|
||||
src2: tagged Invalid,
|
||||
src3: tagged Invalid,
|
||||
dst: tagged Invalid};
|
||||
let rename_result = regRenamingTable.rename[0].getRename (arch_regs);
|
||||
let phy_rindx = fromMaybe (?, rename_result.phy_regs.src1);
|
||||
rf.write [debuggerPort].wr (phy_rindx, data_in);
|
||||
@@ -1106,8 +1106,8 @@ module mkCore#(CoreId coreId)(Core);
|
||||
f_gpr_rsps.enq (rsp);
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_gpr_write: reg %0d <= 0x%0h (phy_rindx = %0d)",
|
||||
cur_cycle, regnum, data_in, phy_rindx);
|
||||
$display ("%0d: %m.rl_debug_gpr_write: reg %0d <= 0x%0h (phy_rindx = %0d)",
|
||||
cur_cycle, regnum, data_in, phy_rindx);
|
||||
endrule
|
||||
|
||||
rule rl_debug_gpr_access_busy (rg_core_run_state == CORE_RUNNING);
|
||||
@@ -1127,15 +1127,15 @@ module mkCore#(CoreId coreId)(Core);
|
||||
FIFOF #(DM_CPU_Rsp #(64)) f_fpr_rsps <- mkFIFOF1;
|
||||
|
||||
rule rl_debug_fpr_read ( (rg_core_run_state == CORE_HALTED)
|
||||
&& (! f_gpr_reqs.notEmpty) // prioritize gpr reqs
|
||||
&& (! f_fpr_reqs.first.write));
|
||||
&& (! f_gpr_reqs.notEmpty) // prioritize gpr reqs
|
||||
&& (! f_fpr_reqs.first.write));
|
||||
let req <- pop (f_fpr_reqs);
|
||||
Bit #(5) regnum = req.address;
|
||||
|
||||
let arch_regs = ArchRegs {src1: tagged Valid (tagged Fpu regnum),
|
||||
src2: tagged Invalid,
|
||||
src3: tagged Invalid,
|
||||
dst: tagged Invalid};
|
||||
src2: tagged Invalid,
|
||||
src3: tagged Invalid,
|
||||
dst: tagged Invalid};
|
||||
let rename_result = regRenamingTable.rename[0].getRename (arch_regs);
|
||||
let phy_rindx = fromMaybe (?, rename_result.phy_regs.src1);
|
||||
let data_out = rf.read [debuggerPort].rd1 (phy_rindx);
|
||||
@@ -1144,20 +1144,20 @@ module mkCore#(CoreId coreId)(Core);
|
||||
f_fpr_rsps.enq (rsp);
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_read_fpr: reg %0d => 0x%0h", cur_cycle, regnum, data_out);
|
||||
$display ("%0d: %m.rl_debug_read_fpr: reg %0d => 0x%0h", cur_cycle, regnum, data_out);
|
||||
endrule
|
||||
|
||||
rule rl_debug_fpr_write ( (rg_core_run_state == CORE_HALTED)
|
||||
&& (! f_gpr_reqs.notEmpty) // prioritize gpr reqs
|
||||
&& f_fpr_reqs.first.write);
|
||||
&& (! f_gpr_reqs.notEmpty) // prioritize gpr reqs
|
||||
&& f_fpr_reqs.first.write);
|
||||
let req <- pop (f_fpr_reqs);
|
||||
Bit #(5) regnum = req.address;
|
||||
let data_in = req.data;
|
||||
|
||||
let arch_regs = ArchRegs {src1: tagged Valid (tagged Fpu regnum),
|
||||
src2: tagged Invalid,
|
||||
src3: tagged Invalid,
|
||||
dst: tagged Invalid};
|
||||
src2: tagged Invalid,
|
||||
src3: tagged Invalid,
|
||||
dst: tagged Invalid};
|
||||
let rename_result = regRenamingTable.rename[0].getRename (arch_regs);
|
||||
let phy_rindx = fromMaybe (?, rename_result.phy_regs.src1);
|
||||
rf.write [debuggerPort].wr (phy_rindx, data_in);
|
||||
@@ -1166,19 +1166,19 @@ module mkCore#(CoreId coreId)(Core);
|
||||
f_fpr_rsps.enq (rsp);
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_write_fpr: reg %0d <= 0x%0h (phy_rindx %0d)",
|
||||
cur_cycle, regnum, data_in, phy_rindx);
|
||||
$display ("%0d: %m.rl_debug_write_fpr: reg %0d <= 0x%0h (phy_rindx %0d)",
|
||||
cur_cycle, regnum, data_in, phy_rindx);
|
||||
endrule
|
||||
|
||||
rule rl_debug_fpr_access_busy ( (rg_core_run_state == CORE_RUNNING)
|
||||
&& f_fpr_reqs.notEmpty);
|
||||
&& f_fpr_reqs.notEmpty);
|
||||
|
||||
let req <- pop (f_fpr_reqs);
|
||||
let rsp = DM_CPU_Rsp {ok: False, data: ?};
|
||||
f_fpr_rsps.enq (rsp);
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_fpr_access_busy", cur_cycle);
|
||||
$display ("%0d: %m.rl_debug_fpr_access_busy", cur_cycle);
|
||||
endrule
|
||||
`endif
|
||||
|
||||
@@ -1190,7 +1190,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
FIFOF #(DM_CPU_Rsp #(64)) f_csr_rsps <- mkFIFOF1;
|
||||
|
||||
rule rl_debug_csr_read ( (rg_core_run_state == CORE_HALTED)
|
||||
&& (! f_csr_reqs.first.write));
|
||||
&& (! f_csr_reqs.first.write));
|
||||
let req <- pop (f_csr_reqs);
|
||||
Bit #(12) csr_addr = req.address;
|
||||
let data_out = csrf.rd (unpack (csr_addr));
|
||||
@@ -1199,11 +1199,11 @@ module mkCore#(CoreId coreId)(Core);
|
||||
f_csr_rsps.enq (rsp);
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_read_csr: csr [%0h] => 0x%0h", cur_cycle, csr_addr, data_out);
|
||||
$display ("%0d: %m.rl_debug_read_csr: csr [%0h] => 0x%0h", cur_cycle, csr_addr, data_out);
|
||||
endrule
|
||||
|
||||
rule rl_debug_csr_write ( (rg_core_run_state == CORE_HALTED)
|
||||
&& f_csr_reqs.first.write);
|
||||
&& f_csr_reqs.first.write);
|
||||
let req <- pop (f_csr_reqs);
|
||||
Bit #(12) csr_addr = req.address;
|
||||
let data_in = req.data;
|
||||
@@ -1213,7 +1213,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
f_csr_rsps.enq (rsp);
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_write_csr: csr [%0h] <= 0x%0h", cur_cycle, csr_addr, data_in);
|
||||
$display ("%0d: %m.rl_debug_write_csr: csr [%0h] <= 0x%0h", cur_cycle, csr_addr, data_in);
|
||||
endrule
|
||||
|
||||
rule rl_debug_csr_access_busy (rg_core_run_state == CORE_RUNNING);
|
||||
@@ -1222,7 +1222,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
f_csr_rsps.enq (rsp);
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_csr_access_busy", cur_cycle);
|
||||
$display ("%0d: %m.rl_debug_csr_access_busy", cur_cycle);
|
||||
endrule
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
@@ -1235,7 +1235,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
// Debug Module Halt control
|
||||
|
||||
rule rl_debug_halt_req ( (rg_core_run_state == CORE_RUNNING)
|
||||
&& (f_run_halt_reqs.first == False));
|
||||
&& (f_run_halt_reqs.first == False));
|
||||
f_run_halt_reqs.deq;
|
||||
|
||||
// Debugger 'halt' request (e.g., GDB '^C' command)
|
||||
@@ -1243,18 +1243,18 @@ module mkCore#(CoreId coreId)(Core);
|
||||
renameStage.debug_halt_req;
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_halt_req", cur_cycle);
|
||||
$display ("%0d: %m.rl_debug_halt_req", cur_cycle);
|
||||
endrule
|
||||
|
||||
rule rl_debug_halt_req_already_halted ( (rg_core_run_state != CORE_RUNNING)
|
||||
&& (f_run_halt_reqs.first == False));
|
||||
&& (f_run_halt_reqs.first == False));
|
||||
f_run_halt_reqs.deq;
|
||||
|
||||
// Notify debugger that we're halted, but otherwise ignore the request
|
||||
f_run_halt_rsps.enq (False);
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_halt_req_already_halted", cur_cycle);
|
||||
$display ("%0d: %m.rl_debug_halt_req_already_halted", cur_cycle);
|
||||
endrule
|
||||
|
||||
// Monitors when we've reached halted state while running
|
||||
@@ -1265,7 +1265,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
rg_core_run_state <= CORE_HALTED;
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_halted", cur_cycle);
|
||||
$display ("%0d: %m.rl_debug_halted", cur_cycle);
|
||||
endrule
|
||||
|
||||
// ----------------
|
||||
@@ -1273,14 +1273,14 @@ module mkCore#(CoreId coreId)(Core);
|
||||
|
||||
// Resume command when in debug mode
|
||||
rule rl_debug_resume ( (rg_core_run_state == CORE_HALTED)
|
||||
&& (f_run_halt_reqs.first == True)
|
||||
&& (f_run_halt_reqs.first == True)
|
||||
|
||||
// prioritise gpr/fpr/csr read/write requests before resuming
|
||||
&& (! f_gpr_reqs.notEmpty)
|
||||
// prioritise gpr/fpr/csr read/write requests before resuming
|
||||
&& (! f_gpr_reqs.notEmpty)
|
||||
`ifdef ISA_F
|
||||
&& (! f_fpr_reqs.notEmpty)
|
||||
&& (! f_fpr_reqs.notEmpty)
|
||||
`endif
|
||||
&& (! f_csr_reqs.notEmpty));
|
||||
&& (! f_csr_reqs.notEmpty));
|
||||
|
||||
f_run_halt_reqs.deq;
|
||||
|
||||
@@ -1312,14 +1312,14 @@ module mkCore#(CoreId coreId)(Core);
|
||||
|
||||
// Run command when already running
|
||||
rule rl_debug_run_redundant ( (rg_core_run_state == CORE_RUNNING)
|
||||
&& (f_run_halt_reqs.first == True));
|
||||
&& (f_run_halt_reqs.first == True));
|
||||
f_run_halt_reqs.deq;
|
||||
|
||||
// Notify debugger that we're running
|
||||
f_run_halt_rsps.enq (True);
|
||||
|
||||
if (show_DM_interactions)
|
||||
$display ("%0d: %m.rl_debug_run_redundant", cur_cycle);
|
||||
$display ("%0d: %m.rl_debug_run_redundant", cur_cycle);
|
||||
endrule
|
||||
|
||||
// ================================================================
|
||||
@@ -1340,7 +1340,7 @@ module mkCore#(CoreId coreId)(Core);
|
||||
);
|
||||
started <= True;
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
rg_core_run_state <= CORE_RUNNING;
|
||||
rg_core_run_state <= CORE_RUNNING;
|
||||
`endif
|
||||
mmio.setHtifAddrs(toHostAddr, fromHostAddr);
|
||||
|
||||
|
||||
@@ -87,9 +87,9 @@ interface CsrFile;
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
// Returns new fcsr and mstatus (pure function)
|
||||
method Tuple2 #(Bit #(5), Data) fpuInst_csr_updates (Bit #(5) fflags,
|
||||
Bool init_for_way0,
|
||||
Bit #(5) old_fflags,
|
||||
Data old_mstatus);
|
||||
Bool init_for_way0,
|
||||
Bit #(5) old_fflags,
|
||||
Data old_mstatus);
|
||||
method Data getMIP;
|
||||
`endif
|
||||
|
||||
@@ -357,22 +357,22 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
ie_vec[prvS], ie_vec[prvU]
|
||||
);
|
||||
function Data fn_mstatus_val (Bit #(2) sxl_val, Bit #(2) uxl_val,
|
||||
Bit #(1) tsr_val, Bit #(1) tw_val, Bit #(1) tvm_val,
|
||||
Bit #(1) mxr_val, Bit #(1) sum_val, Bit #(1) mprv_val,
|
||||
Bit #(2) xs_val, Bit #(2) fs_val,
|
||||
Bit #(2) mpp_val, Bit #(1) spp_val,
|
||||
Bit #(1) prev_ie_vec_prvM_val,
|
||||
Bit #(1) prev_ie_vec_prvS_val, Bit #(1) prev_ie_vec_prvU_val,
|
||||
Bit #(1) ie_vec_prvM_val,
|
||||
Bit #(1) ie_vec_prvS_val, Bit #(1) ie_vec_prvU_val);
|
||||
Bit #(1) tsr_val, Bit #(1) tw_val, Bit #(1) tvm_val,
|
||||
Bit #(1) mxr_val, Bit #(1) sum_val, Bit #(1) mprv_val,
|
||||
Bit #(2) xs_val, Bit #(2) fs_val,
|
||||
Bit #(2) mpp_val, Bit #(1) spp_val,
|
||||
Bit #(1) prev_ie_vec_prvM_val,
|
||||
Bit #(1) prev_ie_vec_prvS_val, Bit #(1) prev_ie_vec_prvU_val,
|
||||
Bit #(1) ie_vec_prvM_val,
|
||||
Bit #(1) ie_vec_prvS_val, Bit #(1) ie_vec_prvU_val);
|
||||
return {fn_sd_val (xs_val, fs_val),
|
||||
27'b0, sxl_val, uxl_val, 9'b0,
|
||||
tsr_val, tw_val, tvm_val, mxr_val, sum_val, mprv_val, xs_val, fs_val,
|
||||
mpp_val, 2'b0, spp_val,
|
||||
prev_ie_vec_prvM_val, 1'b0,
|
||||
prev_ie_vec_prvS_val, prev_ie_vec_prvU_val,
|
||||
ie_vec_prvM_val, 1'b0,
|
||||
ie_vec_prvS_val, ie_vec_prvU_val};
|
||||
27'b0, sxl_val, uxl_val, 9'b0,
|
||||
tsr_val, tw_val, tvm_val, mxr_val, sum_val, mprv_val, xs_val, fs_val,
|
||||
mpp_val, 2'b0, spp_val,
|
||||
prev_ie_vec_prvM_val, 1'b0,
|
||||
prev_ie_vec_prvS_val, prev_ie_vec_prvU_val,
|
||||
ie_vec_prvM_val, 1'b0,
|
||||
ie_vec_prvS_val, ie_vec_prvU_val};
|
||||
endfunction
|
||||
|
||||
// misa
|
||||
@@ -512,21 +512,21 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
readOnlyReg(2'b0), ie_vec[prvS], ie_vec[prvU]
|
||||
);
|
||||
function Data fn_sstatus_val (Bit #(2) uxl_val,
|
||||
Bit #(1) mxr_val, Bit #(1) sum_val,
|
||||
Bit #(2) xs_val, Bit #(2) fs_val,
|
||||
Bit #(1) spp_val,
|
||||
Bit #(1) prev_ie_vec_prvS_val,
|
||||
Bit #(1) prev_ie_vec_prvU_val,
|
||||
Bit #(1) ie_vec_prvS_val,
|
||||
Bit #(1) ie_vec_prvU_val);
|
||||
Bit #(1) mxr_val, Bit #(1) sum_val,
|
||||
Bit #(2) xs_val, Bit #(2) fs_val,
|
||||
Bit #(1) spp_val,
|
||||
Bit #(1) prev_ie_vec_prvS_val,
|
||||
Bit #(1) prev_ie_vec_prvU_val,
|
||||
Bit #(1) ie_vec_prvS_val,
|
||||
Bit #(1) ie_vec_prvU_val);
|
||||
return {fn_sd_val (xs_val, fs_val),
|
||||
27'b0, 2'b0, uxl_val, 12'b0,
|
||||
mxr_val, sum_val, 1'b0, xs_val, fs_val,
|
||||
4'b0, spp_val,
|
||||
2'b0,
|
||||
prev_ie_vec_prvS_val, prev_ie_vec_prvU_val,
|
||||
2'b0,
|
||||
ie_vec_prvS_val, ie_vec_prvU_val};
|
||||
27'b0, 2'b0, uxl_val, 12'b0,
|
||||
mxr_val, sum_val, 1'b0, xs_val, fs_val,
|
||||
4'b0, spp_val,
|
||||
2'b0,
|
||||
prev_ie_vec_prvS_val, prev_ie_vec_prvU_val,
|
||||
2'b0,
|
||||
ie_vec_prvS_val, ie_vec_prvU_val};
|
||||
endfunction
|
||||
|
||||
// sie: restricted view of mie
|
||||
@@ -644,20 +644,20 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
// DCSR is 32b even in RV64
|
||||
Bit #(32) dcsr_reset_value = {4'h4, // [31:28] xdebugver
|
||||
12'h0, // [27:16] reserved
|
||||
1'h0, // [15] ebreakm
|
||||
1'h0, // [14] reserved
|
||||
1'h0, // [13] ebreaks
|
||||
1'h0, // [12] ebreaku
|
||||
1'h0, // [11] stepie
|
||||
1'h0, // [10] stopcount
|
||||
1'h0, // [9] stoptime
|
||||
3'h0, // [8:6] cause // WARNING: 0 is non-standard
|
||||
1'h0, // [5] reserved
|
||||
1'h1, // [4] mprven
|
||||
1'h0, // [3] nmip // non-maskable interrupt pending
|
||||
1'h0, // [2] step
|
||||
2'h3}; // [1:0] prv (machine mode)
|
||||
12'h0, // [27:16] reserved
|
||||
1'h0, // [15] ebreakm
|
||||
1'h0, // [14] reserved
|
||||
1'h0, // [13] ebreaks
|
||||
1'h0, // [12] ebreaku
|
||||
1'h0, // [11] stepie
|
||||
1'h0, // [10] stopcount
|
||||
1'h0, // [9] stoptime
|
||||
3'h0, // [8:6] cause // WARNING: 0 is non-standard
|
||||
1'h0, // [5] reserved
|
||||
1'h1, // [4] mprven
|
||||
1'h0, // [3] nmip // non-maskable interrupt pending
|
||||
1'h0, // [2] step
|
||||
2'h3}; // [1:0] prv (machine mode)
|
||||
|
||||
// RV64: dcsr's upper 32b zeroExtended/ignored
|
||||
Reg #(Data) rg_dcsr <- mkConfigReg (zeroExtend (dcsr_reset_value));
|
||||
@@ -773,16 +773,16 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
CSRtrng: trng_csr;
|
||||
`endif
|
||||
|
||||
CSRtselect: rg_tselect;
|
||||
CSRtdata1: rg_tdata1;
|
||||
CSRtdata2: rg_tdata2;
|
||||
CSRtdata3: rg_tdata3;
|
||||
CSRtselect: rg_tselect;
|
||||
CSRtdata1: rg_tdata1;
|
||||
CSRtdata2: rg_tdata2;
|
||||
CSRtdata3: rg_tdata3;
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
CSRdcsr: rg_dcsr; // TODO: take NMI into account (cf. Piccolo/Flute)
|
||||
CSRdpc: rg_dpc;
|
||||
CSRdscratch0: rg_dscratch0;
|
||||
CSRdscratch1: rg_dscratch1;
|
||||
CSRdcsr: rg_dcsr; // TODO: take NMI into account (cf. Piccolo/Flute)
|
||||
CSRdpc: rg_dpc;
|
||||
CSRdscratch0: rg_dscratch0;
|
||||
CSRdscratch1: rg_dscratch1;
|
||||
`endif
|
||||
|
||||
default: readOnlyReg(64'b0);
|
||||
@@ -801,70 +801,70 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
Asid x_asid = truncate (x [59:44]);
|
||||
Bit #(16) asid = zeroExtend (x_asid);
|
||||
return (
|
||||
case (csr)
|
||||
// Machine CSRs
|
||||
CSRmisa: {getXLBits, 36'b0, getExtensionBits(isa)};
|
||||
CSRmvendorid: 0;
|
||||
CSRmarchid: 0;
|
||||
CSRmimpid: 0;
|
||||
CSRmhartid: hartid;
|
||||
CSRmstatus: fn_mstatus_val (getXLBits, // sxl
|
||||
getXLBits, // uxl
|
||||
x [22], // tsr
|
||||
x [21], // tw
|
||||
x [20], // tvm
|
||||
x [19], // mxr
|
||||
x [18], // sum
|
||||
x [17], // mprv
|
||||
2'b0, // xs
|
||||
((isa.f || isa.d) ? x [14:13] : 2'b0), // fs
|
||||
x [12:11], // mpp
|
||||
x [8], // spp
|
||||
x [7], // prev_ie_vec[prvM]
|
||||
x [5], // prev_ie_vec[prvS]
|
||||
x [4], // prev_ie_vec[prvU]
|
||||
x [3], // ie_vec[prvM]
|
||||
x [1], // ie_vec[prvS]
|
||||
x [0]); // ie_vec[prvU]
|
||||
CSRmtvec: { x[63:2], 1'b0, x[0]};
|
||||
CSRmedeleg: { 48'b0, x[15], 1'b0, x[13:12], x[11], 1'b0, x[9:0]};
|
||||
CSRmideleg: { 52'b0, x[11], 1'b0, x[9:8], x[7], 1'b0, x[5:4], x[3], 1'b0, x[1:0]};
|
||||
CSRmip: ((mip_csr & (~ mip_mie_warl_mask)) | (x & mip_mie_warl_mask));
|
||||
CSRmie: (x & mip_mie_warl_mask);
|
||||
CSRmcounteren: { 61'b0, x[2:0]};
|
||||
CSRmcause: { x[63], 59'b0, x[3:0] };
|
||||
case (csr)
|
||||
// Machine CSRs
|
||||
CSRmisa: {getXLBits, 36'b0, getExtensionBits(isa)};
|
||||
CSRmvendorid: 0;
|
||||
CSRmarchid: 0;
|
||||
CSRmimpid: 0;
|
||||
CSRmhartid: hartid;
|
||||
CSRmstatus: fn_mstatus_val (getXLBits, // sxl
|
||||
getXLBits, // uxl
|
||||
x [22], // tsr
|
||||
x [21], // tw
|
||||
x [20], // tvm
|
||||
x [19], // mxr
|
||||
x [18], // sum
|
||||
x [17], // mprv
|
||||
2'b0, // xs
|
||||
((isa.f || isa.d) ? x [14:13] : 2'b0), // fs
|
||||
x [12:11], // mpp
|
||||
x [8], // spp
|
||||
x [7], // prev_ie_vec[prvM]
|
||||
x [5], // prev_ie_vec[prvS]
|
||||
x [4], // prev_ie_vec[prvU]
|
||||
x [3], // ie_vec[prvM]
|
||||
x [1], // ie_vec[prvS]
|
||||
x [0]); // ie_vec[prvU]
|
||||
CSRmtvec: { x[63:2], 1'b0, x[0]};
|
||||
CSRmedeleg: { 48'b0, x[15], 1'b0, x[13:12], x[11], 1'b0, x[9:0]};
|
||||
CSRmideleg: { 52'b0, x[11], 1'b0, x[9:8], x[7], 1'b0, x[5:4], x[3], 1'b0, x[1:0]};
|
||||
CSRmip: ((mip_csr & (~ mip_mie_warl_mask)) | (x & mip_mie_warl_mask));
|
||||
CSRmie: (x & mip_mie_warl_mask);
|
||||
CSRmcounteren: { 61'b0, x[2:0]};
|
||||
CSRmcause: { x[63], 59'b0, x[3:0] };
|
||||
|
||||
CSRtdata1: { 4'b0, x [59:0] }; // Force tdata.type == 0 ("no trigger at this tselect")
|
||||
CSRtdata1: { 4'b0, x [59:0] }; // Force tdata.type == 0 ("no trigger at this tselect")
|
||||
|
||||
// Supervisor level CSRs
|
||||
CSRsstatus: fn_sstatus_val (getXLBits, // uxl
|
||||
x [19], // mxr
|
||||
x [18], // sum
|
||||
2'b0, // xs
|
||||
((isa.f || isa.d) ? x [14:13] : 2'b0), // fs
|
||||
x [8], // spp
|
||||
x [5], // prev_ie_vec[prvS]
|
||||
x [4], // prev_ie_vec[prvU]
|
||||
x [1], // ie_vec[prvS]
|
||||
x [0]); // ie_vec[prvU]
|
||||
CSRstvec: { x[63:2], 1'b0, x[0]};
|
||||
CSRsip: ((sip_csr & (~ sip_sie_warl_mask)) | (x & sip_sie_warl_mask));
|
||||
CSRsie: (x & sip_sie_warl_mask);
|
||||
CSRscounteren: { 61'b0, x[2:0]};
|
||||
CSRscause: { x[63], 59'b0, x[3:0] };
|
||||
CSRsatp: { x[63], 3'b0, asid, x [43:0] };
|
||||
// Supervisor level CSRs
|
||||
CSRsstatus: fn_sstatus_val (getXLBits, // uxl
|
||||
x [19], // mxr
|
||||
x [18], // sum
|
||||
2'b0, // xs
|
||||
((isa.f || isa.d) ? x [14:13] : 2'b0), // fs
|
||||
x [8], // spp
|
||||
x [5], // prev_ie_vec[prvS]
|
||||
x [4], // prev_ie_vec[prvU]
|
||||
x [1], // ie_vec[prvS]
|
||||
x [0]); // ie_vec[prvU]
|
||||
CSRstvec: { x[63:2], 1'b0, x[0]};
|
||||
CSRsip: ((sip_csr & (~ sip_sie_warl_mask)) | (x & sip_sie_warl_mask));
|
||||
CSRsie: (x & sip_sie_warl_mask);
|
||||
CSRscounteren: { 61'b0, x[2:0]};
|
||||
CSRscause: { x[63], 59'b0, x[3:0] };
|
||||
CSRsatp: { x[63], 3'b0, asid, x [43:0] };
|
||||
|
||||
// User level CSRs
|
||||
CSRfflags: { 59'b0, x [4:0] };
|
||||
CSRfrm: { 61'b0, x [2:0] };
|
||||
CSRfcsr: { 56'b0, x [7:0] };
|
||||
// User level CSRs
|
||||
CSRfflags: { 59'b0, x [4:0] };
|
||||
CSRfrm: { 61'b0, x [2:0] };
|
||||
CSRfcsr: { 56'b0, x [7:0] };
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
// Debug Mode CSRs
|
||||
CSRdcsr: { 32'b0, x[31:28], 12'b0, x[14], 1'b0, x[13:6], 1'b0, x[4:0] };
|
||||
// Debug Mode CSRs
|
||||
CSRdcsr: { 32'b0, x[31:28], 12'b0, x[14], 1'b0, x[13:6], 1'b0, x[4:0] };
|
||||
`endif
|
||||
|
||||
default: x;
|
||||
default: x;
|
||||
endcase);
|
||||
endfunction
|
||||
|
||||
@@ -879,9 +879,9 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
get_csr(csr)._write(x);
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
if (csr == CSRdcsr) begin
|
||||
let prv = x [1:0];
|
||||
prv_reg <= prv;
|
||||
end
|
||||
let prv = x [1:0];
|
||||
prv_reg <= prv;
|
||||
end
|
||||
`endif
|
||||
endmethod
|
||||
|
||||
@@ -901,9 +901,9 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
method Tuple2 #(Bit #(5), Data) fpuInst_csr_updates (Bit #(5) fflags,
|
||||
Bool init_for_way0,
|
||||
Bit #(5) old_fflags,
|
||||
Data old_mstatus);
|
||||
Bool init_for_way0,
|
||||
Bit #(5) old_fflags,
|
||||
Data old_mstatus);
|
||||
|
||||
// Note: old_fflags and old_mstatus are accumulated in
|
||||
// sequential program order, and so may differ from fflags_reg
|
||||
@@ -966,10 +966,10 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
tagged Exception .e: begin
|
||||
cause_code = pack(e);
|
||||
trap_val = (case(e)
|
||||
IllegalInst: zeroExtend (orig_inst);
|
||||
IllegalInst: zeroExtend (orig_inst);
|
||||
InstAddrMisaligned, Breakpoint: return pc;
|
||||
|
||||
InstAccessFault, InstPageFault,
|
||||
InstAccessFault, InstPageFault,
|
||||
LoadAddrMisaligned, LoadAccessFault,
|
||||
StoreAddrMisaligned, StoreAccessFault,
|
||||
LoadPageFault, StorePageFault: return addr;
|
||||
@@ -1013,24 +1013,24 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
stval_csr <= trap_val;
|
||||
// return next pc
|
||||
// return getNextPc(stvec_mode_low_reg, stvec_base_hi_reg);
|
||||
Data sstatus_val = fn_sstatus_val (uxl_reg,
|
||||
mxr_reg, sum_reg,
|
||||
xs_reg, fs_reg,
|
||||
/* spp_reg */ prv_reg [0],
|
||||
/* prev_ie_vec_[prvS] */ ie_vec[prvS],
|
||||
prev_ie_vec [prvU],
|
||||
/* ie_vec [prvS] */ 0,
|
||||
ie_vec [prvU]);
|
||||
Data scause_val = fn_scause_val (cause_interrupt, cause_code);
|
||||
return Trap_Updates {new_pc: getNextPc(stvec_mode_low_reg, stvec_base_hi_reg)
|
||||
Data sstatus_val = fn_sstatus_val (uxl_reg,
|
||||
mxr_reg, sum_reg,
|
||||
xs_reg, fs_reg,
|
||||
/* spp_reg */ prv_reg [0],
|
||||
/* prev_ie_vec_[prvS] */ ie_vec[prvS],
|
||||
prev_ie_vec [prvU],
|
||||
/* ie_vec [prvS] */ 0,
|
||||
ie_vec [prvU]);
|
||||
Data scause_val = fn_scause_val (cause_interrupt, cause_code);
|
||||
return Trap_Updates {new_pc: getNextPc(stvec_mode_low_reg, stvec_base_hi_reg)
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
, prv: prvS,
|
||||
status: sstatus_val,
|
||||
cause: scause_val,
|
||||
epc: pc,
|
||||
tval: trap_val
|
||||
, prv: prvS,
|
||||
status: sstatus_val,
|
||||
cause: scause_val,
|
||||
epc: pc,
|
||||
tval: trap_val
|
||||
`endif
|
||||
};
|
||||
};
|
||||
end
|
||||
else begin
|
||||
// ie/prv stack
|
||||
@@ -1045,27 +1045,27 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
mtval_csr <= trap_val;
|
||||
// return next pc
|
||||
// return getNextPc(mtvec_mode_low_reg, mtvec_base_hi_reg);
|
||||
Data mstatus_val = fn_mstatus_val (sxl_reg, uxl_reg,
|
||||
tsr_reg, tw_reg, tvm_reg,
|
||||
mxr_reg, sum_reg, mprv_reg,
|
||||
xs_reg, fs_reg,
|
||||
/* mpp */ prv_reg, spp_reg,
|
||||
/* prev_ie_vec [prvM] */ ie_vec [prvM],
|
||||
prev_ie_vec [prvS],
|
||||
prev_ie_vec [prvU],
|
||||
/* ie_vec [prvM] */ 0,
|
||||
ie_vec [prvS],
|
||||
ie_vec [prvU]);
|
||||
Data mcause_val = fn_mcause_val (cause_interrupt, cause_code);
|
||||
return Trap_Updates {new_pc: getNextPc(mtvec_mode_low_reg, mtvec_base_hi_reg)
|
||||
Data mstatus_val = fn_mstatus_val (sxl_reg, uxl_reg,
|
||||
tsr_reg, tw_reg, tvm_reg,
|
||||
mxr_reg, sum_reg, mprv_reg,
|
||||
xs_reg, fs_reg,
|
||||
/* mpp */ prv_reg, spp_reg,
|
||||
/* prev_ie_vec [prvM] */ ie_vec [prvM],
|
||||
prev_ie_vec [prvS],
|
||||
prev_ie_vec [prvU],
|
||||
/* ie_vec [prvM] */ 0,
|
||||
ie_vec [prvS],
|
||||
ie_vec [prvU]);
|
||||
Data mcause_val = fn_mcause_val (cause_interrupt, cause_code);
|
||||
return Trap_Updates {new_pc: getNextPc(mtvec_mode_low_reg, mtvec_base_hi_reg)
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
, prv: prvM,
|
||||
status: mstatus_val,
|
||||
cause: mcause_val,
|
||||
epc: pc,
|
||||
tval: trap_val
|
||||
, prv: prvM,
|
||||
status: mstatus_val,
|
||||
cause: mcause_val,
|
||||
epc: pc,
|
||||
tval: trap_val
|
||||
`endif
|
||||
};
|
||||
};
|
||||
end
|
||||
// XXX yield load reservation should be done outside this method
|
||||
endmethod
|
||||
@@ -1077,23 +1077,23 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
prev_ie_vec[prvM] <= 1;
|
||||
|
||||
Data mstatus_val = fn_mstatus_val(sxl_reg, uxl_reg,
|
||||
tsr_reg, tw_reg, tvm_reg,
|
||||
mxr_reg, sum_reg, mprv_reg,
|
||||
xs_reg, fs_reg,
|
||||
/* mpp */ prvU,
|
||||
spp_reg,
|
||||
/* prev_ie_vec [prvM] */ 1,
|
||||
prev_ie_vec [prvS],
|
||||
prev_ie_vec [prvU],
|
||||
/* ie_vec [prvM] */ prev_ie_vec[prvM],
|
||||
ie_vec [prvS],
|
||||
ie_vec [prvU]);
|
||||
tsr_reg, tw_reg, tvm_reg,
|
||||
mxr_reg, sum_reg, mprv_reg,
|
||||
xs_reg, fs_reg,
|
||||
/* mpp */ prvU,
|
||||
spp_reg,
|
||||
/* prev_ie_vec [prvM] */ 1,
|
||||
prev_ie_vec [prvS],
|
||||
prev_ie_vec [prvU],
|
||||
/* ie_vec [prvM] */ prev_ie_vec[prvM],
|
||||
ie_vec [prvS],
|
||||
ie_vec [prvU]);
|
||||
return RET_Updates {new_pc: mepc_csr
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
, prv: prev_prv_vec[prvM],
|
||||
status: mstatus_val
|
||||
, prv: prev_prv_vec[prvM],
|
||||
status: mstatus_val
|
||||
`endif
|
||||
};
|
||||
};
|
||||
endmethod
|
||||
|
||||
method ActionValue#(RET_Updates) sret;
|
||||
@@ -1104,25 +1104,25 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
|
||||
// For Tandem Verification, we return the full underlying MSTATUS register
|
||||
Data mstatus_val = fn_mstatus_val(sxl_reg, uxl_reg,
|
||||
tsr_reg, tw_reg, tvm_reg,
|
||||
mxr_reg, sum_reg, mprv_reg,
|
||||
xs_reg, fs_reg,
|
||||
mpp_reg,
|
||||
/* spp_reg */ prvU [0],
|
||||
tsr_reg, tw_reg, tvm_reg,
|
||||
mxr_reg, sum_reg, mprv_reg,
|
||||
xs_reg, fs_reg,
|
||||
mpp_reg,
|
||||
/* spp_reg */ prvU [0],
|
||||
|
||||
prev_ie_vec [prvM],
|
||||
/* prev_ie_vec_[prvS] */ 1,
|
||||
prev_ie_vec [prvU],
|
||||
prev_ie_vec [prvM],
|
||||
/* prev_ie_vec_[prvS] */ 1,
|
||||
prev_ie_vec [prvU],
|
||||
|
||||
ie_vec [prvM],
|
||||
/* ie_vec [prvS] */ prev_ie_vec[prvS],
|
||||
ie_vec [prvU]);
|
||||
ie_vec [prvM],
|
||||
/* ie_vec [prvS] */ prev_ie_vec[prvS],
|
||||
ie_vec [prvU]);
|
||||
return RET_Updates {new_pc: sepc_csr
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
, prv: prev_prv_vec[prvS],
|
||||
status: mstatus_val
|
||||
, prv: prev_prv_vec[prvS],
|
||||
status: mstatus_val
|
||||
`endif
|
||||
};
|
||||
};
|
||||
endmethod
|
||||
|
||||
method VMInfo vmI;
|
||||
@@ -1244,10 +1244,10 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
// Check whether to enter Debug Mode based on dcsr.{ebreakm, ebreaks, ebreaku}
|
||||
method Bit #(1) dcsr_break_bit;
|
||||
return case (prv_reg)
|
||||
prvM: rg_dcsr [15];
|
||||
prvS: rg_dcsr [13];
|
||||
prvU: rg_dcsr [12];
|
||||
endcase;
|
||||
prvM: rg_dcsr [15];
|
||||
prvS: rg_dcsr [13];
|
||||
prvU: rg_dcsr [12];
|
||||
endcase;
|
||||
endmethod
|
||||
|
||||
// Check whether to enter Debug Mode based on dcsr.step
|
||||
@@ -1262,7 +1262,7 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
|
||||
/*
|
||||
$display ("%0d: %m mkCsrFile.method-dcsr_cause_write: cause %0d, prv %0d",
|
||||
cur_cycle, dcsr_cause, prv_reg);
|
||||
cur_cycle, dcsr_cause, prv_reg);
|
||||
*/
|
||||
endmethod
|
||||
|
||||
|
||||
@@ -46,10 +46,10 @@ endinterface
|
||||
module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
(LLC_AXI4_Adapter_IFC)
|
||||
provisos(Bits#(idT, a__),
|
||||
Bits#(childT, b__),
|
||||
FShow#(ToMemMsg#(idT, childT)),
|
||||
FShow#(MemRsMsg#(idT, childT)),
|
||||
Add#(SizeOf#(Line), 0, 512)); // assert Line sz = 512
|
||||
Bits#(childT, b__),
|
||||
FShow#(ToMemMsg#(idT, childT)),
|
||||
FShow#(MemRsMsg#(idT, childT)),
|
||||
Add#(SizeOf#(Line), 0, 512)); // assert Line sz = 512
|
||||
|
||||
// Verbosity: 0: quiet; 1: LLC transactions; 2: loop detail
|
||||
Integer verbosity = 0;
|
||||
@@ -69,60 +69,60 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
// Send a read-request into the fabric
|
||||
function Action fa_fabric_send_read_req (Fabric_Addr addr);
|
||||
action
|
||||
AXI4_Size size = axsize_8;
|
||||
let mem_req_rd_addr = AXI4_Rd_Addr {arid: fabric_default_id,
|
||||
araddr: addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: size,
|
||||
arburst: fabric_default_burst,
|
||||
arlock: fabric_default_lock,
|
||||
arcache: fabric_default_arcache,
|
||||
arprot: fabric_default_prot,
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_user};
|
||||
AXI4_Size size = axsize_8;
|
||||
let mem_req_rd_addr = AXI4_Rd_Addr {arid: fabric_default_id,
|
||||
araddr: addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: size,
|
||||
arburst: fabric_default_burst,
|
||||
arlock: fabric_default_lock,
|
||||
arcache: fabric_default_arcache,
|
||||
arprot: fabric_default_prot,
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_user};
|
||||
|
||||
master_xactor.i_rd_addr.enq (mem_req_rd_addr);
|
||||
master_xactor.i_rd_addr.enq (mem_req_rd_addr);
|
||||
|
||||
// Debugging
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display (" ", fshow (mem_req_rd_addr));
|
||||
end
|
||||
// Debugging
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display (" ", fshow (mem_req_rd_addr));
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
// Send a write-request into the fabric
|
||||
function Action fa_fabric_send_write_req (Fabric_Addr addr, Fabric_Strb strb, Bit #(64) st_val);
|
||||
action
|
||||
AXI4_Size size = axsize_8;
|
||||
let mem_req_wr_addr = AXI4_Wr_Addr {awid: fabric_default_id,
|
||||
awaddr: addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: size,
|
||||
awburst: fabric_default_burst,
|
||||
awlock: fabric_default_lock,
|
||||
awcache: fabric_default_awcache,
|
||||
awprot: fabric_default_prot,
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: fabric_default_user};
|
||||
AXI4_Size size = axsize_8;
|
||||
let mem_req_wr_addr = AXI4_Wr_Addr {awid: fabric_default_id,
|
||||
awaddr: addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: size,
|
||||
awburst: fabric_default_burst,
|
||||
awlock: fabric_default_lock,
|
||||
awcache: fabric_default_awcache,
|
||||
awprot: fabric_default_prot,
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: fabric_default_user};
|
||||
|
||||
let mem_req_wr_data = AXI4_Wr_Data {wdata: st_val,
|
||||
wstrb: strb,
|
||||
wlast: True,
|
||||
wuser: fabric_default_user};
|
||||
let mem_req_wr_data = AXI4_Wr_Data {wdata: st_val,
|
||||
wstrb: strb,
|
||||
wlast: True,
|
||||
wuser: fabric_default_user};
|
||||
|
||||
master_xactor.i_wr_addr.enq (mem_req_wr_addr);
|
||||
master_xactor.i_wr_data.enq (mem_req_wr_data);
|
||||
master_xactor.i_wr_addr.enq (mem_req_wr_addr);
|
||||
master_xactor.i_wr_data.enq (mem_req_wr_data);
|
||||
|
||||
// Expect a fabric response
|
||||
ctr_wr_rsps_pending.incr;
|
||||
// Expect a fabric response
|
||||
ctr_wr_rsps_pending.incr;
|
||||
|
||||
// Debugging
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display (" To fabric: ", fshow (mem_req_wr_addr));
|
||||
$display (" ", fshow (mem_req_wr_data));
|
||||
end
|
||||
// Debugging
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display (" To fabric: ", fshow (mem_req_wr_addr));
|
||||
$display (" ", fshow (mem_req_wr_data));
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -138,11 +138,11 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
Reg #(Bit #(512)) rg_cline <- mkRegU;
|
||||
|
||||
rule rl_handle_read_req (llc.toM.first matches tagged Ld .ld
|
||||
&&& (ctr_wr_rsps_pending.value == 0));
|
||||
&&& (ctr_wr_rsps_pending.value == 0));
|
||||
if ((cfg_verbosity > 0) && (rg_rd_req_beat == 0)) begin
|
||||
$display ("%0d: LLC_AXI4_Adapter.rl_handle_read_req: Ld request from LLC to memory: beat %0d",
|
||||
cur_cycle, rg_rd_req_beat);
|
||||
$display (" ", fshow (ld));
|
||||
$display ("%0d: LLC_AXI4_Adapter.rl_handle_read_req: Ld request from LLC to memory: beat %0d",
|
||||
cur_cycle, rg_rd_req_beat);
|
||||
$display (" ", fshow (ld));
|
||||
end
|
||||
|
||||
Addr line_addr = { ld.addr [63:6], 6'h0 }; // Addr of containing cache line
|
||||
@@ -150,10 +150,10 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
fa_fabric_send_read_req (line_addr | offset);
|
||||
|
||||
if (rg_rd_req_beat == 0)
|
||||
f_pending_reads.enq (ld);
|
||||
f_pending_reads.enq (ld);
|
||||
|
||||
if (rg_rd_req_beat == 7)
|
||||
llc.toM.deq;
|
||||
llc.toM.deq;
|
||||
|
||||
rg_rd_req_beat <= rg_rd_req_beat + 1;
|
||||
endrule
|
||||
@@ -162,30 +162,30 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
let mem_rsp <- pop_o (master_xactor.o_rd_data);
|
||||
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: LLC_AXI4_Adapter.rl_handle_read_rsps: beat %0d ", cur_cycle, rg_rd_rsp_beat);
|
||||
$display (" ", fshow (mem_rsp));
|
||||
$display ("%0d: LLC_AXI4_Adapter.rl_handle_read_rsps: beat %0d ", cur_cycle, rg_rd_rsp_beat);
|
||||
$display (" ", fshow (mem_rsp));
|
||||
end
|
||||
|
||||
if (mem_rsp.rresp != axi4_resp_okay) begin
|
||||
// TODO: need to raise a non-maskable interrupt (NMI) here
|
||||
$display ("%0d: LLC_AXI4_Adapter.rl_handle_read_rsp: fabric response error; exit", cur_cycle);
|
||||
$display (" ", fshow (mem_rsp));
|
||||
$finish (1);
|
||||
// TODO: need to raise a non-maskable interrupt (NMI) here
|
||||
$display ("%0d: LLC_AXI4_Adapter.rl_handle_read_rsp: fabric response error; exit", cur_cycle);
|
||||
$display (" ", fshow (mem_rsp));
|
||||
$finish (1);
|
||||
end
|
||||
|
||||
// Shift next 64 bits from fabric into the cache line being assembled
|
||||
let new_cline = { mem_rsp.rdata, rg_cline [511:64] };
|
||||
|
||||
if (rg_rd_rsp_beat == 7) begin
|
||||
let ldreq <- pop (f_pending_reads);
|
||||
MemRsMsg #(idT, childT) resp = MemRsMsg {data: unpack (new_cline),
|
||||
child: ldreq.child,
|
||||
id: ldreq.id};
|
||||
let ldreq <- pop (f_pending_reads);
|
||||
MemRsMsg #(idT, childT) resp = MemRsMsg {data: unpack (new_cline),
|
||||
child: ldreq.child,
|
||||
id: ldreq.id};
|
||||
|
||||
llc.rsFromM.enq (resp);
|
||||
llc.rsFromM.enq (resp);
|
||||
|
||||
if (cfg_verbosity > 1)
|
||||
$display (" Response to LLC: ", fshow (resp));
|
||||
if (cfg_verbosity > 1)
|
||||
$display (" Response to LLC: ", fshow (resp));
|
||||
end
|
||||
|
||||
rg_cline <= new_cline;
|
||||
@@ -203,8 +203,8 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
|
||||
rule rl_handle_write_req (llc.toM.first matches tagged Wb .wb);
|
||||
if ((cfg_verbosity > 0) && (rg_wr_req_beat == 0)) begin
|
||||
$display ("%d: LLC_AXI4_Adapter.rl_handle_write_req: Wb request from LLC to memory:", cur_cycle);
|
||||
$display (" ", fshow (wb));
|
||||
$display ("%d: LLC_AXI4_Adapter.rl_handle_write_req: Wb request from LLC to memory:", cur_cycle);
|
||||
$display (" ", fshow (wb));
|
||||
end
|
||||
|
||||
Addr line_addr = { wb.addr [63:6], 6'h0 }; // Addr of containing cache line
|
||||
@@ -217,10 +217,10 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
fa_fabric_send_write_req (line_addr | offset, strb8, data64);
|
||||
|
||||
if (rg_wr_req_beat == 0)
|
||||
f_pending_writes.enq (wb);
|
||||
f_pending_writes.enq (wb);
|
||||
|
||||
if (rg_wr_req_beat == 7)
|
||||
llc.toM.deq;
|
||||
llc.toM.deq;
|
||||
|
||||
rg_wr_req_beat <= rg_wr_req_beat + 1;
|
||||
endrule
|
||||
@@ -232,29 +232,29 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
let wr_resp <- pop_o (master_xactor.o_wr_resp);
|
||||
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: LLC_AXI4_Adapter.rl_discard_write_rsp: beat %0d ", cur_cycle, rg_wr_rsp_beat);
|
||||
$display (" ", fshow (wr_resp));
|
||||
$display ("%0d: LLC_AXI4_Adapter.rl_discard_write_rsp: beat %0d ", cur_cycle, rg_wr_rsp_beat);
|
||||
$display (" ", fshow (wr_resp));
|
||||
end
|
||||
|
||||
if (ctr_wr_rsps_pending.value == 0) begin
|
||||
$display ("%0d: ERROR: LLC_AXI4_Adapter.rl_discard_write_rsp: unexpected Wr response (ctr_wr_rsps_pending.value == 0)",
|
||||
cur_cycle);
|
||||
$display (" ", fshow (wr_resp));
|
||||
$finish (1); // Assertion failure
|
||||
$display ("%0d: ERROR: LLC_AXI4_Adapter.rl_discard_write_rsp: unexpected Wr response (ctr_wr_rsps_pending.value == 0)",
|
||||
cur_cycle);
|
||||
$display (" ", fshow (wr_resp));
|
||||
$finish (1); // Assertion failure
|
||||
end
|
||||
|
||||
ctr_wr_rsps_pending.decr;
|
||||
|
||||
if (wr_resp.bresp != axi4_resp_okay) begin
|
||||
// TODO: need to raise a non-maskable interrupt (NMI) here
|
||||
$display ("%0d: LLC_AXI4_Adapter.rl_discard_write_rsp: fabric response error: exit", cur_cycle);
|
||||
$display (" ", fshow (wr_resp));
|
||||
$finish (1);
|
||||
// TODO: need to raise a non-maskable interrupt (NMI) here
|
||||
$display ("%0d: LLC_AXI4_Adapter.rl_discard_write_rsp: fabric response error: exit", cur_cycle);
|
||||
$display (" ", fshow (wr_resp));
|
||||
$finish (1);
|
||||
end
|
||||
|
||||
if (rg_wr_rsp_beat == 7) begin
|
||||
let wrreq <- pop (f_pending_writes);
|
||||
// LLC does not expect any response for writes
|
||||
let wrreq <- pop (f_pending_writes);
|
||||
// LLC does not expect any response for writes
|
||||
end
|
||||
|
||||
rg_wr_rsp_beat <= rg_wr_rsp_beat + 1;
|
||||
|
||||
@@ -81,31 +81,31 @@ function Bit #(64) fn_extract_and_extend_bytes (Bit #(2) sz, Bit #(64) byte_addr
|
||||
|
||||
case (sz)
|
||||
sz_B: case (addr_lsbs)
|
||||
'h0: result = zeroExtend (word64 [ 7: 0]);
|
||||
'h1: result = zeroExtend (word64 [15: 8]);
|
||||
'h2: result = zeroExtend (word64 [23:16]);
|
||||
'h3: result = zeroExtend (word64 [31:24]);
|
||||
'h4: result = zeroExtend (word64 [39:32]);
|
||||
'h5: result = zeroExtend (word64 [47:40]);
|
||||
'h6: result = zeroExtend (word64 [55:48]);
|
||||
'h7: result = zeroExtend (word64 [63:56]);
|
||||
endcase
|
||||
'h0: result = zeroExtend (word64 [ 7: 0]);
|
||||
'h1: result = zeroExtend (word64 [15: 8]);
|
||||
'h2: result = zeroExtend (word64 [23:16]);
|
||||
'h3: result = zeroExtend (word64 [31:24]);
|
||||
'h4: result = zeroExtend (word64 [39:32]);
|
||||
'h5: result = zeroExtend (word64 [47:40]);
|
||||
'h6: result = zeroExtend (word64 [55:48]);
|
||||
'h7: result = zeroExtend (word64 [63:56]);
|
||||
endcase
|
||||
|
||||
sz_H: case (addr_lsbs)
|
||||
'h0: result = zeroExtend (word64 [15: 0]);
|
||||
'h2: result = zeroExtend (word64 [31:16]);
|
||||
'h4: result = zeroExtend (word64 [47:32]);
|
||||
'h6: result = zeroExtend (word64 [63:48]);
|
||||
endcase
|
||||
'h0: result = zeroExtend (word64 [15: 0]);
|
||||
'h2: result = zeroExtend (word64 [31:16]);
|
||||
'h4: result = zeroExtend (word64 [47:32]);
|
||||
'h6: result = zeroExtend (word64 [63:48]);
|
||||
endcase
|
||||
|
||||
sz_W: case (addr_lsbs)
|
||||
'h0: result = zeroExtend (word64 [31: 0]);
|
||||
'h4: result = zeroExtend (word64 [63:32]);
|
||||
endcase
|
||||
'h0: result = zeroExtend (word64 [31: 0]);
|
||||
'h4: result = zeroExtend (word64 [63:32]);
|
||||
endcase
|
||||
|
||||
sz_D: case (addr_lsbs) // D
|
||||
'h0: result = word64;
|
||||
endcase
|
||||
'h0: result = word64;
|
||||
endcase
|
||||
endcase
|
||||
return result;
|
||||
endfunction
|
||||
@@ -127,31 +127,31 @@ function Bit #(64) fn_update_bytes (Bit #(2) sz, Bit #(64) byte_addr, Bit #(64)
|
||||
|
||||
case (sz)
|
||||
sz_B: case (addr_lsbs)
|
||||
'h0: result = { st_val [63:8], value [7:0] };
|
||||
'h1: result = { st_val [63:16], value [7:0], st_val [7:0] };
|
||||
'h2: result = { st_val [63:24], value [7:0], st_val [15:0] };
|
||||
'h3: result = { st_val [63:32], value [7:0], st_val [23:0] };
|
||||
'h4: result = { st_val [63:40], value [7:0], st_val [31:0] };
|
||||
'h5: result = { st_val [63:48], value [7:0], st_val [39:0] };
|
||||
'h6: result = { st_val [63:56], value [7:0], st_val [47:0] };
|
||||
'h7: result = { value [7:0], st_val [55:0] };
|
||||
endcase
|
||||
'h0: result = { st_val [63:8], value [7:0] };
|
||||
'h1: result = { st_val [63:16], value [7:0], st_val [7:0] };
|
||||
'h2: result = { st_val [63:24], value [7:0], st_val [15:0] };
|
||||
'h3: result = { st_val [63:32], value [7:0], st_val [23:0] };
|
||||
'h4: result = { st_val [63:40], value [7:0], st_val [31:0] };
|
||||
'h5: result = { st_val [63:48], value [7:0], st_val [39:0] };
|
||||
'h6: result = { st_val [63:56], value [7:0], st_val [47:0] };
|
||||
'h7: result = { value [7:0], st_val [55:0] };
|
||||
endcase
|
||||
|
||||
sz_H: case (addr_lsbs)
|
||||
'h0: result = { st_val [63:16], value [15:0] };
|
||||
'h2: result = { st_val [63:32], value [15:0], st_val [15:0] };
|
||||
'h4: result = { st_val [63:48], value [15:0], st_val [31:0] };
|
||||
'h6: result = { value [15:0], st_val [47:0] };
|
||||
endcase
|
||||
'h0: result = { st_val [63:16], value [15:0] };
|
||||
'h2: result = { st_val [63:32], value [15:0], st_val [15:0] };
|
||||
'h4: result = { st_val [63:48], value [15:0], st_val [31:0] };
|
||||
'h6: result = { value [15:0], st_val [47:0] };
|
||||
endcase
|
||||
|
||||
sz_W: case (addr_lsbs)
|
||||
'h0: result = { st_val [63:32], value [31:0] };
|
||||
'h4: result = { value [31:0], st_val [31:0] };
|
||||
endcase
|
||||
'h0: result = { st_val [63:32], value [31:0] };
|
||||
'h4: result = { value [31:0], st_val [31:0] };
|
||||
endcase
|
||||
|
||||
sz_D: case (addr_lsbs) // D
|
||||
'h0: result = st_val;
|
||||
endcase
|
||||
'h0: result = st_val;
|
||||
endcase
|
||||
endcase
|
||||
return result;
|
||||
endfunction
|
||||
@@ -163,10 +163,10 @@ endfunction
|
||||
// Updates the relevant bytes of st_val.
|
||||
|
||||
function Bit #(64) fn_amo_op (Bit #(2) sz, // encodes data size (.W or .D)
|
||||
AmoFunc amofunc, // encodes the AMO op
|
||||
Bit #(64) addr, // lsbs indicate which 32b W in 64b D (.W)
|
||||
Bit #(64) ld_val, // 64b value loaded from mem
|
||||
Bit #(64) st_val); // 64b value from CPU reg Rs2
|
||||
AmoFunc amofunc, // encodes the AMO op
|
||||
Bit #(64) addr, // lsbs indicate which 32b W in 64b D (.W)
|
||||
Bit #(64) ld_val, // 64b value loaded from mem
|
||||
Bit #(64) st_val); // 64b value from CPU reg Rs2
|
||||
// Extract relevant bytes of ld_val and st_val
|
||||
Bit #(64) w1 = fn_extract_and_extend_bytes (sz, addr, ld_val);
|
||||
Bit #(64) w2 = fn_extract_and_extend_bytes (sz, addr, st_val);
|
||||
@@ -232,7 +232,7 @@ typedef union tagged {
|
||||
} MMIOPlatformReq deriving(Bits, Eq, FShow);
|
||||
|
||||
module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
Server #(MMIOCRq, MMIODataPRs) mmio_fabric_adapter_core_side)
|
||||
Server #(MMIOCRq, MMIODataPRs) mmio_fabric_adapter_core_side)
|
||||
(MMIOPlatform)
|
||||
|
||||
provisos (Bits #(Data, 64)); // this module assumes Data is 64-bit wide
|
||||
@@ -268,7 +268,7 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
Reg#(SupWaySel) fetchingWay <- mkRegU;
|
||||
// the already fetched insts
|
||||
Vector#(TSub#(SupSize, 1),
|
||||
Reg#(Instruction)) fetchedInsts <- replicateM(mkRegU);
|
||||
Reg#(Instruction)) fetchedInsts <- replicateM(mkRegU);
|
||||
|
||||
// we need to wait for resp from cores when we need to change MTIP
|
||||
Reg#(Vector#(CoreNum, Bool)) waitMTIPCRs <- mkRegU;
|
||||
@@ -323,13 +323,13 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
Vector#(CoreNum, Bool) needTimerInt = replicate(False);
|
||||
for(Integer i = 0; i < valueof(CoreNum); i = i+1) begin
|
||||
if(!mtip[i] && mtimecmp[i] <= mtime) begin
|
||||
cores[i].pRq.enq(MMIOPRq {
|
||||
target: MTIP,
|
||||
func: St,
|
||||
data: 1
|
||||
cores[i].pRq.enq(MMIOPRq {
|
||||
target: MTIP,
|
||||
func: St,
|
||||
data: 1
|
||||
});
|
||||
mtip[i] <= True;
|
||||
needTimerInt[i] = True;
|
||||
mtip[i] <= True;
|
||||
needTimerInt[i] = True;
|
||||
end
|
||||
end
|
||||
if(needTimerInt != replicate(False)) begin
|
||||
@@ -337,11 +337,11 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
curReq <= TimerInterrupt;
|
||||
waitMTIPCRs <= needTimerInt;
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - SelectReq] timer interrupt",
|
||||
", mtime %x", mtime,
|
||||
", mtimcmp ", fshow(readVReg(mtimecmp)),
|
||||
", old mtip ", fshow(readVReg(mtip)),
|
||||
", new interrupts ", fshow(needTimerInt));
|
||||
$display("[Platform - SelectReq] timer interrupt",
|
||||
", mtime %x", mtime,
|
||||
", mtimcmp ", fshow(readVReg(mtimecmp)),
|
||||
", old mtip ", fshow(readVReg(mtip)),
|
||||
", new interrupts ", fshow(needTimerInt));
|
||||
end
|
||||
end
|
||||
else begin
|
||||
@@ -349,57 +349,57 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
function Bool hasReq(Integer i) = cores[i].cRq.notEmpty;
|
||||
Vector#(CoreNum, Integer) idxVec = genVector;
|
||||
if(find(hasReq, idxVec) matches tagged Valid .i) begin
|
||||
cores[i].cRq.deq;
|
||||
MMIOCRq req = cores[i].cRq.first;
|
||||
// record req
|
||||
reqCore <= fromInteger(i);
|
||||
reqFunc <= req.func;
|
||||
reqAmofunc <= case (req.func) matches
|
||||
tagged Amo .f : f;
|
||||
default: None;
|
||||
endcase;
|
||||
reqBE <= req.byteEn;
|
||||
reqData <= req.data;
|
||||
reqSz <= sz_D; // TODO: may be sz_H, sz_B or sz_W
|
||||
// set up bookkeepings in case of inst fetch (other
|
||||
// bookkeepings are set at processing time)
|
||||
instSel <= truncate(req.addr >> valueof(LgInstSzBytes));
|
||||
fetchingWay <= 0;
|
||||
// find out which MMIO reg/device is being requested
|
||||
DataAlignedAddr addr = getDataAlignedAddr(req.addr);
|
||||
MMIOPlatformReq newReq = Invalid;
|
||||
cores[i].cRq.deq;
|
||||
MMIOCRq req = cores[i].cRq.first;
|
||||
// record req
|
||||
reqCore <= fromInteger(i);
|
||||
reqFunc <= req.func;
|
||||
reqAmofunc <= case (req.func) matches
|
||||
tagged Amo .f : f;
|
||||
default: None;
|
||||
endcase;
|
||||
reqBE <= req.byteEn;
|
||||
reqData <= req.data;
|
||||
reqSz <= sz_D; // TODO: may be sz_H, sz_B or sz_W
|
||||
// set up bookkeepings in case of inst fetch (other
|
||||
// bookkeepings are set at processing time)
|
||||
instSel <= truncate(req.addr >> valueof(LgInstSzBytes));
|
||||
fetchingWay <= 0;
|
||||
// find out which MMIO reg/device is being requested
|
||||
DataAlignedAddr addr = getDataAlignedAddr(req.addr);
|
||||
MMIOPlatformReq newReq = Invalid;
|
||||
|
||||
if(addr >= msipBaseAddr && addr < msipBoundAddr) begin
|
||||
newReq = MSIP (truncate(addr - msipBaseAddr));
|
||||
end
|
||||
if(addr >= msipBaseAddr && addr < msipBoundAddr) begin
|
||||
newReq = MSIP (truncate(addr - msipBaseAddr));
|
||||
end
|
||||
else if(addr >= mtimecmpBaseAddr &&
|
||||
addr < mtimecmpBoundAddr)
|
||||
begin
|
||||
newReq = MTimeCmp (truncate(addr - mtimecmpBaseAddr));
|
||||
end
|
||||
addr < mtimecmpBoundAddr)
|
||||
begin
|
||||
newReq = MTimeCmp (truncate(addr - mtimecmpBaseAddr));
|
||||
end
|
||||
else if(addr == mtimeBaseAddr) begin
|
||||
// assume mtime is of size Data
|
||||
newReq = MTime;
|
||||
end
|
||||
// assume mtime is of size Data
|
||||
newReq = MTime;
|
||||
end
|
||||
else if(addr == toHostAddr) begin
|
||||
// assume tohost is of size Data
|
||||
newReq = ToHost;
|
||||
end
|
||||
// assume tohost is of size Data
|
||||
newReq = ToHost;
|
||||
end
|
||||
else if(addr == fromHostAddr) begin
|
||||
// assume fromhost is of size Data
|
||||
newReq = FromHost;
|
||||
end
|
||||
// assume fromhost is of size Data
|
||||
newReq = FromHost;
|
||||
end
|
||||
else begin // Send all remaining reqs to the fabric adapter, as is
|
||||
newReq = MMIO_Fabric_Adapter (req.addr);
|
||||
end
|
||||
newReq = MMIO_Fabric_Adapter (req.addr);
|
||||
end
|
||||
curReq <= newReq;
|
||||
|
||||
// process valid req
|
||||
state <= ProcessReq;
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - SelectReq] core %d, req ", i, fshow(req));
|
||||
$display(" req type ", fshow(newReq));
|
||||
end
|
||||
// process valid req
|
||||
state <= ProcessReq;
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - SelectReq] core %d, req ", i, fshow(req));
|
||||
$display(" req type ", fshow(newReq));
|
||||
end
|
||||
end
|
||||
end
|
||||
endrule
|
||||
@@ -408,14 +408,14 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
rule waitTimerInterruptDone(state == WaitResp && curReq == TimerInterrupt);
|
||||
for(Integer i = 0; i < valueof(CoreNum); i = i+1) begin
|
||||
if(waitMTIPCRs[i]) begin
|
||||
cores[i].cRs.deq;
|
||||
cores[i].cRs.deq;
|
||||
end
|
||||
end
|
||||
state <= SelectReq;
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - Done] timer interrupt",
|
||||
", mtip ", fshow(readVReg(mtip)),
|
||||
", waitCRs ", fshow(waitMTIPCRs));
|
||||
", mtip ", fshow(readVReg(mtip)),
|
||||
", waitCRs ", fshow(waitMTIPCRs));
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -442,17 +442,17 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
state <= SelectReq;
|
||||
cores[reqCore].pRs.enq(InstFetch (replicate(Invalid)));
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - process msip] cannot do inst fetch");
|
||||
$display("[Platform - process msip] cannot do inst fetch");
|
||||
end
|
||||
end
|
||||
else if(upper_en && !upper_valid) begin
|
||||
// access invalid core's MSIP, fault
|
||||
state <= SelectReq;
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: False, data: ?
|
||||
}));
|
||||
valid: False, data: ?
|
||||
}));
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - process msip] access invalid core");
|
||||
$display("[Platform - process msip] access invalid core");
|
||||
end
|
||||
end
|
||||
else if(reqFunc matches tagged Amo .amoFunc) begin
|
||||
@@ -461,61 +461,61 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
// resp is different from load that valid data is already shifted
|
||||
// to LSBs). Besides, we only use the lower 32 bits of reqData.
|
||||
if(lower_en && upper_en) begin
|
||||
state <= SelectReq;
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: False, data: ?
|
||||
}));
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - process msip] ",
|
||||
"AMO cannot access 2 cores");
|
||||
end
|
||||
state <= SelectReq;
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: False, data: ?
|
||||
}));
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - process msip] ",
|
||||
"AMO cannot access 2 cores");
|
||||
end
|
||||
end
|
||||
else if(lower_en) begin
|
||||
cores[lower_core].pRq.enq(MMIOPRq {
|
||||
target: MSIP,
|
||||
func: reqFunc,
|
||||
data: truncate(reqData)
|
||||
});
|
||||
waitLowerMSIPCRs <= Valid (lower_core);
|
||||
waitUpperMSIPCRs <= Invalid;
|
||||
state <= WaitResp;
|
||||
cores[lower_core].pRq.enq(MMIOPRq {
|
||||
target: MSIP,
|
||||
func: reqFunc,
|
||||
data: truncate(reqData)
|
||||
});
|
||||
waitLowerMSIPCRs <= Valid (lower_core);
|
||||
waitUpperMSIPCRs <= Invalid;
|
||||
state <= WaitResp;
|
||||
end
|
||||
else if(upper_en) begin
|
||||
cores[upper_core].pRq.enq(MMIOPRq {
|
||||
target: MSIP,
|
||||
func: reqFunc,
|
||||
data: truncate(reqData)
|
||||
});
|
||||
waitLowerMSIPCRs <= Valid (upper_core);
|
||||
waitUpperMSIPCRs <= Invalid;
|
||||
state <= WaitResp;
|
||||
cores[upper_core].pRq.enq(MMIOPRq {
|
||||
target: MSIP,
|
||||
func: reqFunc,
|
||||
data: truncate(reqData)
|
||||
});
|
||||
waitLowerMSIPCRs <= Valid (upper_core);
|
||||
waitUpperMSIPCRs <= Invalid;
|
||||
state <= WaitResp;
|
||||
end
|
||||
else begin
|
||||
// AMO access nothing: fault
|
||||
state <= SelectReq;
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: False, data: ?
|
||||
}));
|
||||
if(verbosity > 0) begin
|
||||
// AMO access nothing: fault
|
||||
state <= SelectReq;
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: False, data: ?
|
||||
}));
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - process msip] access nothing");
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else begin
|
||||
// normal load and store
|
||||
if(lower_en) begin
|
||||
cores[lower_core].pRq.enq(MMIOPRq {
|
||||
target: MSIP,
|
||||
func: reqFunc,
|
||||
data: zeroExtend(reqData[0])
|
||||
});
|
||||
cores[lower_core].pRq.enq(MMIOPRq {
|
||||
target: MSIP,
|
||||
func: reqFunc,
|
||||
data: zeroExtend(reqData[0])
|
||||
});
|
||||
end
|
||||
if(upper_en) begin
|
||||
cores[upper_core].pRq.enq(MMIOPRq {
|
||||
target: MSIP,
|
||||
func: reqFunc,
|
||||
data: zeroExtend(reqData[32])
|
||||
});
|
||||
cores[upper_core].pRq.enq(MMIOPRq {
|
||||
target: MSIP,
|
||||
func: reqFunc,
|
||||
data: zeroExtend(reqData[32])
|
||||
});
|
||||
end
|
||||
state <= WaitResp;
|
||||
waitLowerMSIPCRs <= lower_en ? Valid (lower_core) : Invalid;
|
||||
@@ -524,33 +524,33 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
endrule
|
||||
|
||||
rule waitMSIPDone(
|
||||
curReq matches tagged MSIP .offset &&& state == WaitResp
|
||||
);
|
||||
curReq matches tagged MSIP .offset &&& state == WaitResp
|
||||
);
|
||||
Bit#(32) lower_data = 0;
|
||||
Bit#(32) upper_data = 0;
|
||||
for(Integer i = 0; i < valueof(CoreNum); i = i+1) begin
|
||||
if (waitLowerMSIPCRs matches tagged Valid .c &&&
|
||||
c == fromInteger(i)) begin
|
||||
cores[i].cRs.deq;
|
||||
lower_data = zeroExtend(cores[i].cRs.first.data);
|
||||
end
|
||||
else if(waitUpperMSIPCRs matches tagged Valid .c &&&
|
||||
c == fromInteger(i)) begin
|
||||
cores[i].cRs.deq;
|
||||
upper_data = zeroExtend(cores[i].cRs.first.data);
|
||||
end
|
||||
c == fromInteger(i)) begin
|
||||
cores[i].cRs.deq;
|
||||
lower_data = zeroExtend(cores[i].cRs.first.data);
|
||||
end
|
||||
else if(waitUpperMSIPCRs matches tagged Valid .c &&&
|
||||
c == fromInteger(i)) begin
|
||||
cores[i].cRs.deq;
|
||||
upper_data = zeroExtend(cores[i].cRs.first.data);
|
||||
end
|
||||
end
|
||||
state <= SelectReq;
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: True,
|
||||
// for AMO, resp data should be signExtend(lower_data). However,
|
||||
// lower_data is just 1 or 0, and upper_data is always 0, so we
|
||||
// don't need to do signExtend.
|
||||
data: {upper_data, lower_data}
|
||||
}));
|
||||
valid: True,
|
||||
// for AMO, resp data should be signExtend(lower_data). However,
|
||||
// lower_data is just 1 or 0, and upper_data is always 0, so we
|
||||
// don't need to do signExtend.
|
||||
data: {upper_data, lower_data}
|
||||
}));
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - msip done] lower %x, upper %x",
|
||||
lower_data, upper_data);
|
||||
lower_data, upper_data);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -560,11 +560,11 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
Bool doubleWord = reqBE[4] && reqBE[0];
|
||||
Bool upper32 = reqBE[4] && !reqBE[0];
|
||||
let amoInst = AmoInst {
|
||||
func: amoFunc,
|
||||
doubleWord: doubleWord,
|
||||
aq: False,
|
||||
rl: False
|
||||
};
|
||||
func: amoFunc,
|
||||
doubleWord: doubleWord,
|
||||
aq: False,
|
||||
rl: False
|
||||
};
|
||||
return amoExec(amoInst, orig, reqData, upper32);
|
||||
end
|
||||
else begin
|
||||
@@ -572,9 +572,9 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
Vector#(NumBytes, Bit#(8)) data = unpack(orig);
|
||||
Vector#(NumBytes, Bit#(8)) wrVec = unpack(reqData);
|
||||
for(Integer i = 0; i < valueof(NumBytes); i = i+1) begin
|
||||
if(reqBE[i]) begin
|
||||
data[i] = wrVec[i];
|
||||
end
|
||||
if(reqBE[i]) begin
|
||||
data[i] = wrVec[i];
|
||||
end
|
||||
end
|
||||
return pack(data);
|
||||
end
|
||||
@@ -597,81 +597,81 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
|
||||
// handle mtimecmp access
|
||||
rule processMTimeCmp(
|
||||
curReq matches tagged MTimeCmp .offset &&& state == ProcessReq
|
||||
curReq matches tagged MTimeCmp .offset &&& state == ProcessReq
|
||||
);
|
||||
if(isInstFetch) begin
|
||||
state <= SelectReq;
|
||||
cores[reqCore].pRs.enq(InstFetch (replicate(Invalid)));
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - process mtimecmp] cannot do inst fetch");
|
||||
$display("[Platform - process mtimecmp] cannot do inst fetch");
|
||||
end
|
||||
end
|
||||
else if(offset > fromInteger(valueof(CoreNum) - 1)) begin
|
||||
// access invalid core's mtimecmp, fault
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: False, data: ?
|
||||
}));
|
||||
valid: False, data: ?
|
||||
}));
|
||||
state <= SelectReq;
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - process mtimecmp] access fault");
|
||||
$display("[Platform - process mtimecmp] access fault");
|
||||
end
|
||||
end
|
||||
else begin
|
||||
let oldMTimeCmp = mtimecmp[offset];
|
||||
if(reqFunc == Ld) begin
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: True,
|
||||
data: oldMTimeCmp
|
||||
}));
|
||||
state <= SelectReq;
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - process mtimecmp] read done, data %x",
|
||||
oldMTimeCmp);
|
||||
end
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: True,
|
||||
data: oldMTimeCmp
|
||||
}));
|
||||
state <= SelectReq;
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - process mtimecmp] read done, data %x",
|
||||
oldMTimeCmp);
|
||||
end
|
||||
end
|
||||
else begin
|
||||
// do updates for store or AMO
|
||||
let newData = getWriteData(oldMTimeCmp);
|
||||
mtimecmp[offset] <= newData;
|
||||
// get and record amo resp
|
||||
let respData = getAmoResp(oldMTimeCmp);
|
||||
amoResp <= respData;
|
||||
// check changes to MTIP
|
||||
if(newData <= mtime && !mtip[offset]) begin
|
||||
// need to post new timer interrupt
|
||||
mtip[offset] <= True;
|
||||
cores[offset].pRq.enq(MMIOPRq {
|
||||
target: MTIP,
|
||||
func: St,
|
||||
// do updates for store or AMO
|
||||
let newData = getWriteData(oldMTimeCmp);
|
||||
mtimecmp[offset] <= newData;
|
||||
// get and record amo resp
|
||||
let respData = getAmoResp(oldMTimeCmp);
|
||||
amoResp <= respData;
|
||||
// check changes to MTIP
|
||||
if(newData <= mtime && !mtip[offset]) begin
|
||||
// need to post new timer interrupt
|
||||
mtip[offset] <= True;
|
||||
cores[offset].pRq.enq(MMIOPRq {
|
||||
target: MTIP,
|
||||
func: St,
|
||||
data: 1
|
||||
});
|
||||
state <= WaitResp;
|
||||
end
|
||||
});
|
||||
state <= WaitResp;
|
||||
end
|
||||
else if(newData > mtime && mtip[offset]) begin
|
||||
// need to clear timer interrupt
|
||||
mtip[offset] <= False;
|
||||
cores[offset].pRq.enq(MMIOPRq {
|
||||
target: MTIP,
|
||||
func: St,
|
||||
// need to clear timer interrupt
|
||||
mtip[offset] <= False;
|
||||
cores[offset].pRq.enq(MMIOPRq {
|
||||
target: MTIP,
|
||||
func: St,
|
||||
data: 0
|
||||
});
|
||||
state <= WaitResp;
|
||||
end
|
||||
});
|
||||
state <= WaitResp;
|
||||
end
|
||||
else begin
|
||||
// nothing happens to mtip, just finish this req
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: True,
|
||||
// store doesn't need resp data, just fill in AMO resp
|
||||
data: respData
|
||||
// nothing happens to mtip, just finish this req
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: True,
|
||||
// store doesn't need resp data, just fill in AMO resp
|
||||
data: respData
|
||||
}));
|
||||
state <= SelectReq;
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - process mtimecmp] ",
|
||||
"no change to mtip ", fshow(readVReg(mtip)),
|
||||
", mtime %x", mtime,
|
||||
state <= SelectReq;
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - process mtimecmp] ",
|
||||
"no change to mtip ", fshow(readVReg(mtip)),
|
||||
", mtime %x", mtime,
|
||||
", old mtimecmp ", fshow(readVReg(mtimecmp)),
|
||||
", new mtimecmp[%d] %x", offset, newData);
|
||||
end
|
||||
", new mtimecmp[%d] %x", offset, newData);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -682,17 +682,17 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
);
|
||||
cores[offset].cRs.deq;
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: True,
|
||||
// store doesn't need resp data, just fill in AMO resp. We cannot
|
||||
// recompute AMO resp now, because mtimecmp has changed
|
||||
data: amoResp
|
||||
}));
|
||||
valid: True,
|
||||
// store doesn't need resp data, just fill in AMO resp. We cannot
|
||||
// recompute AMO resp now, because mtimecmp has changed
|
||||
data: amoResp
|
||||
}));
|
||||
state <= SelectReq;
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - mtimecmp done]",
|
||||
", mtime %x", mtime,
|
||||
", mtimecmp ", fshow(readVReg(mtimecmp)),
|
||||
", mtip ", fshow(readVReg(mtip)));
|
||||
", mtime %x", mtime,
|
||||
", mtimecmp ", fshow(readVReg(mtimecmp)),
|
||||
", mtip ", fshow(readVReg(mtip)));
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -889,30 +889,30 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
|
||||
// Forward the request as-is to the fabric adapter.
|
||||
rule rl_mmio_to_fabric_req (curReq matches tagged MMIO_Fabric_Adapter .addr
|
||||
&&& (state == ProcessReq)
|
||||
&&& (isLd || isSt));
|
||||
&&& (state == ProcessReq)
|
||||
&&& (isLd || isSt));
|
||||
let req = MMIOCRq {addr:addr, func:reqFunc, byteEn:reqBE, data:reqData};
|
||||
mmio_fabric_adapter_core_side.request.put (req);
|
||||
state <= WaitResp;
|
||||
|
||||
if (verbosity > 0) begin
|
||||
$display ("MMIOPlatform.rl_mmio_to_fabric_req");
|
||||
$display (" ", fshow (req));
|
||||
$display ("MMIOPlatform.rl_mmio_to_fabric_req");
|
||||
$display (" ", fshow (req));
|
||||
end
|
||||
endrule
|
||||
|
||||
// Forward the fabric-adapter's response as-is to the core.
|
||||
rule rl_mmio_from_fabric_rsp (curReq matches tagged MMIO_Fabric_Adapter .addr
|
||||
&&& (state == WaitResp)
|
||||
&&& (isLd || isSt));
|
||||
&&& (state == WaitResp)
|
||||
&&& (isLd || isSt));
|
||||
MMIODataPRs dprs <- mmio_fabric_adapter_core_side.response.get;
|
||||
let prs = tagged DataAccess dprs;
|
||||
cores[reqCore].pRs.enq (prs);
|
||||
state <= SelectReq;
|
||||
|
||||
if (verbosity > 0) begin
|
||||
$display ("MMIOPlatform.rl_mmio_from_fabric_rsp");
|
||||
$display (" ", fshow (prs));
|
||||
$display ("MMIOPlatform.rl_mmio_from_fabric_rsp");
|
||||
$display (" ", fshow (prs));
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -920,8 +920,8 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
// MMIO to Fabric: AMO (not Instruction Fetch)
|
||||
|
||||
rule rl_mmio_to_fabric_amo_req (curReq matches tagged MMIO_Fabric_Adapter .addr
|
||||
&&& (state == ProcessReq)
|
||||
&&& isAmo);
|
||||
&&& (state == ProcessReq)
|
||||
&&& isAmo);
|
||||
// Send a load-request to the fabric adapter.
|
||||
// Align addr to 8-byte boundary (FabricData-aligned)
|
||||
Addr addr1 = { addr [63:3], 3'b_000 };
|
||||
@@ -930,41 +930,41 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
state <= WaitResp;
|
||||
|
||||
if (verbosity > 0) begin
|
||||
$display ("MMIOPlatform.rl_mmio_to_fabric_amo_req: addr 0x%0h", addr);
|
||||
$display (" ", fshow (req));
|
||||
$display ("MMIOPlatform.rl_mmio_to_fabric_amo_req: addr 0x%0h", addr);
|
||||
$display (" ", fshow (req));
|
||||
end
|
||||
endrule
|
||||
|
||||
// Get the Load-response; do the AMO op; send final write back to fabric, and respond to core
|
||||
rule rl_mmio_from_fabric_amo_rsp (curReq matches tagged MMIO_Fabric_Adapter .addr
|
||||
&&& (state == WaitResp)
|
||||
&&& isAmo);
|
||||
&&& (state == WaitResp)
|
||||
&&& isAmo);
|
||||
MMIODataPRs dprs <- mmio_fabric_adapter_core_side.response.get;
|
||||
|
||||
if (! dprs.valid) begin
|
||||
// Access fault
|
||||
let prs = tagged DataAccess dprs;
|
||||
cores[reqCore].pRs.enq (prs);
|
||||
state <= SelectReq;
|
||||
// Access fault
|
||||
let prs = tagged DataAccess dprs;
|
||||
cores[reqCore].pRs.enq (prs);
|
||||
state <= SelectReq;
|
||||
end
|
||||
else begin
|
||||
// Do the AMO op on the loaded value and the store value
|
||||
let ld_val = dprs.data;
|
||||
let new_st_val = fn_amo_op (reqSz, reqAmofunc, addr, ld_val, reqData);
|
||||
// Do the AMO op on the loaded value and the store value
|
||||
let ld_val = dprs.data;
|
||||
let new_st_val = fn_amo_op (reqSz, reqAmofunc, addr, ld_val, reqData);
|
||||
|
||||
// Write back new st_val to fabric
|
||||
let req = MMIOCRq {addr:addr, func:tagged St, byteEn:reqBE, data:new_st_val};
|
||||
mmio_fabric_adapter_core_side.request.put (req);
|
||||
// Write back new st_val to fabric
|
||||
let req = MMIOCRq {addr:addr, func:tagged St, byteEn:reqBE, data:new_st_val};
|
||||
mmio_fabric_adapter_core_side.request.put (req);
|
||||
|
||||
let prs = tagged DataAccess (MMIODataPRs { valid: True, data: ld_val });
|
||||
cores[reqCore].pRs.enq (prs);
|
||||
state <= SelectReq;
|
||||
let prs = tagged DataAccess (MMIODataPRs { valid: True, data: ld_val });
|
||||
cores[reqCore].pRs.enq (prs);
|
||||
state <= SelectReq;
|
||||
|
||||
if (verbosity > 1) begin
|
||||
$display ("MMIO_Platform.rl_mmio_from_fabric_amo_rsp: addr 0x%0h, size %0d, amofunc %0d",
|
||||
addr, reqSz, reqAmofunc);
|
||||
$display (" ld_val 0x%0h op st_val 0x%0h => new_st_val 0x%0h", ld_val, reqData, new_st_val);
|
||||
end
|
||||
if (verbosity > 1) begin
|
||||
$display ("MMIO_Platform.rl_mmio_from_fabric_amo_rsp: addr 0x%0h, size %0d, amofunc %0d",
|
||||
addr, reqSz, reqAmofunc);
|
||||
$display (" ld_val 0x%0h op st_val 0x%0h => new_st_val 0x%0h", ld_val, reqData, new_st_val);
|
||||
end
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -980,8 +980,8 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
// fetchingWay: initial 0
|
||||
|
||||
rule rl_mmio_to_fabric_ifetch_req (curReq matches tagged MMIO_Fabric_Adapter .addr
|
||||
&&& (state == ProcessReq)
|
||||
&&& isInstFetch);
|
||||
&&& (state == ProcessReq)
|
||||
&&& isInstFetch);
|
||||
// Note: addr may not be FabricData-aligned; result will be Data that contains addr
|
||||
// TODO: currently assumes superscalarity fits in fabric width
|
||||
Addr addr1 = { addr [63:3], 3'b_000 };
|
||||
@@ -990,79 +990,79 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
state <= WaitResp;
|
||||
|
||||
if (verbosity > 0) begin
|
||||
$display ("MMIOPlatform.rl_mmio_to_fabric_ifetch_req: addr 0x%0h fetchingWay %0d",
|
||||
addr, fetchingWay);
|
||||
$display (" ", fshow (req));
|
||||
$display ("MMIOPlatform.rl_mmio_to_fabric_ifetch_req: addr 0x%0h fetchingWay %0d",
|
||||
addr, fetchingWay);
|
||||
$display (" ", fshow (req));
|
||||
end
|
||||
endrule
|
||||
|
||||
rule rl_mmio_from_fabric_ifetch_rsp (curReq matches tagged MMIO_Fabric_Adapter .addr
|
||||
&&& (state == WaitResp)
|
||||
&&& isInstFetch);
|
||||
&&& (state == WaitResp)
|
||||
&&& isInstFetch);
|
||||
MMIODataPRs dprs <- mmio_fabric_adapter_core_side.response.get;
|
||||
if (! dprs.valid) begin
|
||||
// Access fault
|
||||
// Access fault
|
||||
Vector #(SupSize, Maybe #(Instruction)) resp = replicate (Invalid);
|
||||
for(Integer i = 0; i < valueof (SupSize); i = i+1) begin
|
||||
if (fromInteger (i) < fetchingWay)
|
||||
resp [i] = Valid (fetchedInsts [i]);
|
||||
if (fromInteger (i) < fetchingWay)
|
||||
resp [i] = Valid (fetchedInsts [i]);
|
||||
else if (fromInteger (i) == fetchingWay)
|
||||
resp [i] = tagged Invalid;
|
||||
resp [i] = tagged Invalid;
|
||||
end
|
||||
cores[reqCore].pRs.enq (tagged InstFetch (resp));
|
||||
state <= SelectReq;
|
||||
|
||||
if (verbosity > 0) begin
|
||||
$display ("MMIOPlatform.rl_mmio_from_fabric_ifetch_rsp: access fault; final resp to core:");
|
||||
$display (" ", fshow (resp));
|
||||
end
|
||||
if (verbosity > 0) begin
|
||||
$display ("MMIOPlatform.rl_mmio_from_fabric_ifetch_rsp: access fault; final resp to core:");
|
||||
$display (" ", fshow (resp));
|
||||
end
|
||||
end
|
||||
|
||||
else begin
|
||||
// No access fault
|
||||
let data = dprs.data;
|
||||
// No access fault
|
||||
let data = dprs.data;
|
||||
|
||||
SupWaySel maxWay = 0;
|
||||
if(reqFunc matches tagged Inst .w) begin
|
||||
maxWay = w;
|
||||
end
|
||||
|
||||
// View Data as a vector of instructions
|
||||
// View Data as a vector of instructions
|
||||
Vector#(DataSzInst, Instruction) instVec = unpack(data);
|
||||
// extract inst from resp data
|
||||
Instruction inst = instVec[instSel];
|
||||
// check whether we are done or not
|
||||
if (fetchingWay >= maxWay) begin
|
||||
// all 0..maxWay insts are fetched; we can resp now
|
||||
// all 0..maxWay insts are fetched; we can resp now
|
||||
Vector#(SupSize, Maybe#(Instruction)) resp = replicate(Invalid);
|
||||
for(Integer i = 0; i < valueof(SupSize); i = i+1) begin
|
||||
if(fromInteger(i) < fetchingWay) begin
|
||||
if(fromInteger(i) < fetchingWay) begin
|
||||
resp[i] = Valid (fetchedInsts[i]);
|
||||
end
|
||||
end
|
||||
else if(fromInteger(i) == fetchingWay) begin
|
||||
resp[i] = Valid (inst);
|
||||
end
|
||||
end
|
||||
end
|
||||
cores[reqCore].pRs.enq (tagged InstFetch (resp));
|
||||
state <= SelectReq;
|
||||
|
||||
if (verbosity > 0) begin
|
||||
$display ("MMIOPlatform.rl_mmio_from_fabric_ifetch_rsp: final resp to core:");
|
||||
$display (" ", fshow (resp));
|
||||
end
|
||||
if (verbosity > 0) begin
|
||||
$display ("MMIOPlatform.rl_mmio_from_fabric_ifetch_rsp: final resp to core:");
|
||||
$display (" ", fshow (resp));
|
||||
end
|
||||
end
|
||||
else begin
|
||||
// continue to fetch next inst, save current inst, increment offset
|
||||
fetchedInsts[fetchingWay] <= inst;
|
||||
fetchingWay <= fetchingWay + 1;
|
||||
instSel <= instSel + 1;
|
||||
curReq <= MMIO_Fabric_Adapter (instSel == maxBound ? addr + 8 : addr);
|
||||
curReq <= MMIO_Fabric_Adapter (instSel == maxBound ? addr + 8 : addr);
|
||||
state <= ProcessReq;
|
||||
|
||||
if (verbosity > 0) begin
|
||||
$display ("MMIOPlatform.rl_mmio_from_fabric_ifetch_rsp:");
|
||||
$display (" fetchingWay %0d instSel %0d inst 0x%0h", fetchingWay, instSel, inst);
|
||||
end
|
||||
if (verbosity > 0) begin
|
||||
$display ("MMIOPlatform.rl_mmio_from_fabric_ifetch_rsp:");
|
||||
$display (" fetchingWay %0d instSel %0d inst 0x%0h", fetchingWay, instSel, inst);
|
||||
end
|
||||
end
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -82,75 +82,75 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
// Send a read-request into the fabric
|
||||
function Action fa_fabric_send_read_req (Fabric_Addr addr);
|
||||
action
|
||||
AXI4_Size size = axsize_8;
|
||||
let mem_req_rd_addr = AXI4_Rd_Addr {arid: fabric_default_id,
|
||||
araddr: addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: size,
|
||||
arburst: fabric_default_burst,
|
||||
arlock: fabric_default_lock,
|
||||
arcache: fabric_default_arcache,
|
||||
arprot: fabric_default_prot,
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_user};
|
||||
AXI4_Size size = axsize_8;
|
||||
let mem_req_rd_addr = AXI4_Rd_Addr {arid: fabric_default_id,
|
||||
araddr: addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: size,
|
||||
arburst: fabric_default_burst,
|
||||
arlock: fabric_default_lock,
|
||||
arcache: fabric_default_arcache,
|
||||
arprot: fabric_default_prot,
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_user};
|
||||
|
||||
master_xactor.i_rd_addr.enq (mem_req_rd_addr);
|
||||
master_xactor.i_rd_addr.enq (mem_req_rd_addr);
|
||||
|
||||
// Debugging
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display (" ", fshow (mem_req_rd_addr));
|
||||
end
|
||||
// Debugging
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display (" ", fshow (mem_req_rd_addr));
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
// Send a write-request into the fabric
|
||||
function Action fa_fabric_send_write_req (Fabric_Addr addr, Fabric_Strb strb, Bit #(64) st_val);
|
||||
action
|
||||
AXI4_Size size = axsize_8;
|
||||
let mem_req_wr_addr = AXI4_Wr_Addr {awid: fabric_default_id,
|
||||
awaddr: addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: size,
|
||||
awburst: fabric_default_burst,
|
||||
awlock: fabric_default_lock,
|
||||
awcache: fabric_default_awcache,
|
||||
awprot: fabric_default_prot,
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: fabric_default_user};
|
||||
AXI4_Size size = axsize_8;
|
||||
let mem_req_wr_addr = AXI4_Wr_Addr {awid: fabric_default_id,
|
||||
awaddr: addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: size,
|
||||
awburst: fabric_default_burst,
|
||||
awlock: fabric_default_lock,
|
||||
awcache: fabric_default_awcache,
|
||||
awprot: fabric_default_prot,
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: fabric_default_user};
|
||||
|
||||
let mem_req_wr_data = AXI4_Wr_Data {wdata: st_val,
|
||||
wstrb: strb,
|
||||
wlast: True,
|
||||
wuser: fabric_default_user};
|
||||
let mem_req_wr_data = AXI4_Wr_Data {wdata: st_val,
|
||||
wstrb: strb,
|
||||
wlast: True,
|
||||
wuser: fabric_default_user};
|
||||
|
||||
`ifdef FABRIC64
|
||||
// Work-around for a misbehavior on Xilinx UART and its
|
||||
// Xilinx AXI4 adapter. On 64-bit fabrics, for a write where
|
||||
// axsize says '8 bytes' but wstrb is for <= 4 bytes, the
|
||||
// adapter converts it two 32-bit writes, one of which has
|
||||
// wstrb=4'b0000. The Xilinx UART, in turn ignores wstrb and
|
||||
// therefore performs a spurious write. This workaround
|
||||
// changes axsize for such writes to '4 bytes', avoiding this
|
||||
// problem.
|
||||
// Work-around for a misbehavior on Xilinx UART and its
|
||||
// Xilinx AXI4 adapter. On 64-bit fabrics, for a write where
|
||||
// axsize says '8 bytes' but wstrb is for <= 4 bytes, the
|
||||
// adapter converts it two 32-bit writes, one of which has
|
||||
// wstrb=4'b0000. The Xilinx UART, in turn ignores wstrb and
|
||||
// therefore performs a spurious write. This workaround
|
||||
// changes axsize for such writes to '4 bytes', avoiding this
|
||||
// problem.
|
||||
|
||||
if (strb [7:4] == 0 || strb [3:0] == 0) begin
|
||||
mem_req_wr_addr.awsize = axsize_4;
|
||||
end
|
||||
if (strb [7:4] == 0 || strb [3:0] == 0) begin
|
||||
mem_req_wr_addr.awsize = axsize_4;
|
||||
end
|
||||
`endif
|
||||
|
||||
master_xactor.i_wr_addr.enq (mem_req_wr_addr);
|
||||
master_xactor.i_wr_data.enq (mem_req_wr_data);
|
||||
master_xactor.i_wr_addr.enq (mem_req_wr_addr);
|
||||
master_xactor.i_wr_data.enq (mem_req_wr_data);
|
||||
|
||||
// Expect a fabric response
|
||||
ctr_wr_rsps_pending.incr;
|
||||
// Expect a fabric response
|
||||
ctr_wr_rsps_pending.incr;
|
||||
|
||||
// Debugging
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display (" To fabric: ", fshow (mem_req_wr_addr));
|
||||
$display (" ", fshow (mem_req_wr_data));
|
||||
end
|
||||
// Debugging
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display (" To fabric: ", fshow (mem_req_wr_addr));
|
||||
$display (" ", fshow (mem_req_wr_data));
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -160,28 +160,28 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
// This is just an adapter from MMIOCRq/MMIODataPRs to AXI4
|
||||
|
||||
rule rl_handle_read_req (f_reqs_from_core.first.func matches Ld
|
||||
&&& (ctr_wr_rsps_pending.value == 0));
|
||||
&&& (ctr_wr_rsps_pending.value == 0));
|
||||
let req <- pop (f_reqs_from_core);
|
||||
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display ("%0d: %m.rl_handle_read_req: Ld request", cur_cycle);
|
||||
$display (" ", fshow (req));
|
||||
$display ("%0d: %m.rl_handle_read_req: Ld request", cur_cycle);
|
||||
$display (" ", fshow (req));
|
||||
end
|
||||
|
||||
// Technically the following check for legal IO addrs is not
|
||||
// necessary; the AXI4 fabric should return a DECERR for illegal
|
||||
// addrs; but not all AXI4 fabrics do the right thing.
|
||||
if (soc_map.m_is_IO_addr (req.addr))
|
||||
fa_fabric_send_read_req (req.addr);
|
||||
fa_fabric_send_read_req (req.addr);
|
||||
else begin
|
||||
let rsp = MMIODataPRs {valid: False,
|
||||
data: req.addr}; // For debugging convenience only
|
||||
f_rsps_to_core.enq (rsp);
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display ("%0d: %m.rl_handle_read_req: unmapped IO address; returning error response",
|
||||
cur_cycle);
|
||||
$display (" ", fshow (req));
|
||||
end
|
||||
let rsp = MMIODataPRs {valid: False,
|
||||
data: req.addr}; // For debugging convenience only
|
||||
f_rsps_to_core.enq (rsp);
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display ("%0d: %m.rl_handle_read_req: unmapped IO address; returning error response",
|
||||
cur_cycle);
|
||||
$display (" ", fshow (req));
|
||||
end
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -191,21 +191,21 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
let mem_rsp <- pop_o (master_xactor.o_rd_data);
|
||||
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display ("%0d: %m.rl_handle_read_rsps ", cur_cycle);
|
||||
$display (" ", fshow (mem_rsp));
|
||||
$display ("%0d: %m.rl_handle_read_rsps ", cur_cycle);
|
||||
$display (" ", fshow (mem_rsp));
|
||||
end
|
||||
|
||||
if ((cfg_verbosity > 0) && (mem_rsp.rresp != axi4_resp_okay)) begin
|
||||
$display ("%0d: %m.rl_handle_read_rsp: fabric response error", cur_cycle);
|
||||
$display (" ", fshow (mem_rsp));
|
||||
$display ("%0d: %m.rl_handle_read_rsp: fabric response error", cur_cycle);
|
||||
$display (" ", fshow (mem_rsp));
|
||||
end
|
||||
|
||||
let rsp = MMIODataPRs {valid: (mem_rsp.rresp == axi4_resp_okay),
|
||||
data: mem_rsp.rdata};
|
||||
data: mem_rsp.rdata};
|
||||
f_rsps_to_core.enq (rsp);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display (" Response MMIO to core: ", fshow (rsp));
|
||||
$display (" Response MMIO to core: ", fshow (rsp));
|
||||
endrule
|
||||
|
||||
// ================================================================
|
||||
@@ -215,24 +215,24 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
let req <- pop (f_reqs_from_core);
|
||||
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display ("%d: %m.rl_handle_write_req: St request:", cur_cycle);
|
||||
$display (" ", fshow (req));
|
||||
$display ("%d: %m.rl_handle_write_req: St request:", cur_cycle);
|
||||
$display (" ", fshow (req));
|
||||
end
|
||||
|
||||
// Technically the following check for legal IO addrs is not
|
||||
// necessary; the AXI4 fabric should return a DECERR for illegal
|
||||
// addrs; but not all AXI4 fabrics do the right thing.
|
||||
if (soc_map.m_is_IO_addr (req.addr))
|
||||
fa_fabric_send_write_req (req.addr, pack (req.byteEn), req.data);
|
||||
fa_fabric_send_write_req (req.addr, pack (req.byteEn), req.data);
|
||||
else begin
|
||||
let rsp = MMIODataPRs {valid: False,
|
||||
data: req.addr}; // For debugging convenience only
|
||||
f_rsps_to_core.enq (rsp);
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display ("%0d: %m.rl_handle_write_req: unmapped IO address; returning error response",
|
||||
cur_cycle);
|
||||
$display (" ", fshow (req));
|
||||
end
|
||||
let rsp = MMIODataPRs {valid: False,
|
||||
data: req.addr}; // For debugging convenience only
|
||||
f_rsps_to_core.enq (rsp);
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display ("%0d: %m.rl_handle_write_req: unmapped IO address; returning error response",
|
||||
cur_cycle);
|
||||
$display (" ", fshow (req));
|
||||
end
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -243,28 +243,28 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
let wr_resp <- pop_o (master_xactor.o_wr_resp);
|
||||
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display ("%0d: %m.rl_discard_write_rsp", cur_cycle);
|
||||
$display (" ", fshow (wr_resp));
|
||||
$display ("%0d: %m.rl_discard_write_rsp", cur_cycle);
|
||||
$display (" ", fshow (wr_resp));
|
||||
end
|
||||
|
||||
if (ctr_wr_rsps_pending.value == 0) begin
|
||||
$display ("%0d:%m.rl_discard_write_rsp: ERROR:unexpected Wr response (ctr_wr_rsps_pending.value == 0)",
|
||||
cur_cycle);
|
||||
$display (" ", fshow (wr_resp));
|
||||
$finish (1); // Assertion failure
|
||||
$display ("%0d:%m.rl_discard_write_rsp: ERROR:unexpected Wr response (ctr_wr_rsps_pending.value == 0)",
|
||||
cur_cycle);
|
||||
$display (" ", fshow (wr_resp));
|
||||
$finish (1); // Assertion failure
|
||||
end
|
||||
|
||||
ctr_wr_rsps_pending.decr;
|
||||
|
||||
if (wr_resp.bresp != axi4_resp_okay) begin
|
||||
// TODO: need to raise a non-maskable interrupt (NMI) here
|
||||
$display ("%0d:%m.rl_discard_write_rsp: ERROR: fabric response error: exit.", cur_cycle);
|
||||
$display (" ", fshow (wr_resp));
|
||||
$finish (1);
|
||||
// TODO: need to raise a non-maskable interrupt (NMI) here
|
||||
$display ("%0d:%m.rl_discard_write_rsp: ERROR: fabric response error: exit.", cur_cycle);
|
||||
$display (" ", fshow (wr_resp));
|
||||
$finish (1);
|
||||
end
|
||||
else begin
|
||||
let rsp = MMIODataPRs {valid: True, data: 0};
|
||||
f_rsps_to_core.enq (rsp);
|
||||
let rsp = MMIODataPRs {valid: True, data: 0};
|
||||
f_rsps_to_core.enq (rsp);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -273,10 +273,10 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
|
||||
function Bool fn_is_Ld_or_St (MMIOCRq req);
|
||||
return case (req.func) matches
|
||||
Ld : True;
|
||||
St : True;
|
||||
default: False;
|
||||
endcase;
|
||||
Ld : True;
|
||||
St : True;
|
||||
default: False;
|
||||
endcase;
|
||||
endfunction
|
||||
|
||||
rule rl_handle_non_Ld_St (! fn_is_Ld_or_St (f_reqs_from_core.first));
|
||||
|
||||
@@ -116,7 +116,7 @@ module mkProc (Proc_IFC);
|
||||
mmioToP[i] = core[i].mmioToPlatform;
|
||||
end
|
||||
MMIOPlatform mmioPlatform <- mkMMIOPlatform (mmioToP,
|
||||
mmio_axi4_adapter.core_side);
|
||||
mmio_axi4_adapter.core_side);
|
||||
|
||||
// last level cache
|
||||
LLCache llc <- mkLLCache;
|
||||
@@ -153,7 +153,7 @@ module mkProc (Proc_IFC);
|
||||
rule broadcastStats;
|
||||
Bool doStats <- core[i].sendDoStats;
|
||||
for(Integer j = 0; j < valueof(CoreNum); j = j+1) begin
|
||||
core[j].recvDoStats(doStats);
|
||||
core[j].recvDoStats(doStats);
|
||||
end
|
||||
llc.perf.setStatus(doStats);
|
||||
endrule
|
||||
@@ -164,35 +164,35 @@ module mkProc (Proc_IFC);
|
||||
|
||||
for(Integer j = 0; j < valueof(CoreNum); j = j+1) begin
|
||||
rule rl_dummy1;
|
||||
let x <- core[j].deadlock.dCacheCRqStuck.get;
|
||||
let x <- core[j].deadlock.dCacheCRqStuck.get;
|
||||
endrule
|
||||
rule rl_dummy2;
|
||||
let x <- core[j].deadlock.dCachePRqStuck.get;
|
||||
let x <- core[j].deadlock.dCachePRqStuck.get;
|
||||
endrule
|
||||
rule rl_dummy3;
|
||||
let x <- core[j].deadlock.iCacheCRqStuck.get;
|
||||
let x <- core[j].deadlock.iCacheCRqStuck.get;
|
||||
endrule
|
||||
rule rl_dummy4;
|
||||
let x <- core[j].deadlock.iCachePRqStuck.get;
|
||||
let x <- core[j].deadlock.iCachePRqStuck.get;
|
||||
endrule
|
||||
rule rl_dummy5;
|
||||
let x <- core[j].deadlock.renameInstStuck.get;
|
||||
let x <- core[j].deadlock.renameInstStuck.get;
|
||||
endrule
|
||||
rule rl_dummy6;
|
||||
let x <- core[j].deadlock.renameCorrectPathStuck.get;
|
||||
let x <- core[j].deadlock.renameCorrectPathStuck.get;
|
||||
endrule
|
||||
rule rl_dummy7;
|
||||
let x <- core[j].deadlock.commitInstStuck.get;
|
||||
let x <- core[j].deadlock.commitInstStuck.get;
|
||||
endrule
|
||||
rule rl_dummy8;
|
||||
let x <- core[j].deadlock.commitUserInstStuck.get;
|
||||
let x <- core[j].deadlock.commitUserInstStuck.get;
|
||||
endrule
|
||||
rule rl_dummy9;
|
||||
let x <- core[j].deadlock.checkStarted.get;
|
||||
let x <- core[j].deadlock.checkStarted.get;
|
||||
endrule
|
||||
|
||||
rule rl_dummy20;
|
||||
let x <- core[j].renameDebug.renameErr.get;
|
||||
let x <- core[j].renameDebug.renameErr.get;
|
||||
endrule
|
||||
end
|
||||
|
||||
@@ -201,8 +201,8 @@ module mkProc (Proc_IFC);
|
||||
|
||||
for(Integer i = 0; i < valueof(CoreNum); i = i+1) begin
|
||||
rule rl_terminate;
|
||||
let x <- core[i].coreIndInv.terminate;
|
||||
$display ("Core %d terminated", i);
|
||||
let x <- core[i].coreIndInv.terminate;
|
||||
$display ("Core %d terminated", i);
|
||||
endrule
|
||||
end
|
||||
|
||||
@@ -213,15 +213,15 @@ module mkProc (Proc_IFC);
|
||||
let x <- mmioPlatform.to_host;
|
||||
$display ("%0d: mmioPlatform.rl_tohost: 0x%0x (= %0d)", cur_cycle, x, x);
|
||||
if (x != 0) begin
|
||||
// Standard RISC-V ISA tests finish by writing a value tohost with x[0]==1.
|
||||
// Further when x[63:1]==0, all tests within the program pass,
|
||||
// otherwise x[63:1] = the test within the program that failed.
|
||||
let failed_testnum = (x >> 1);
|
||||
if (failed_testnum == 0)
|
||||
$display ("PASS");
|
||||
else
|
||||
$display ("FAIL %0d", failed_testnum);
|
||||
$finish (0);
|
||||
// Standard RISC-V ISA tests finish by writing a value tohost with x[0]==1.
|
||||
// Further when x[63:1]==0, all tests within the program pass,
|
||||
// otherwise x[63:1] = the test within the program that failed.
|
||||
let failed_testnum = (x >> 1);
|
||||
if (failed_testnum == 0)
|
||||
$display ("PASS");
|
||||
else
|
||||
$display ("FAIL %0d", failed_testnum);
|
||||
$finish (0);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -235,14 +235,14 @@ module mkProc (Proc_IFC);
|
||||
// Use toHostAddr = 0 if not monitoring tohost
|
||||
method Action start (Addr startpc, Addr tohostAddr, Addr fromhostAddr);
|
||||
action
|
||||
for(Integer i = 0; i < valueof(CoreNum); i = i+1)
|
||||
core[i].coreReq.start (startpc, tohostAddr, fromhostAddr);
|
||||
for(Integer i = 0; i < valueof(CoreNum); i = i+1)
|
||||
core[i].coreReq.start (startpc, tohostAddr, fromhostAddr);
|
||||
endaction
|
||||
|
||||
mmioPlatform.start (tohostAddr, fromhostAddr);
|
||||
|
||||
$display ("%0d: %m.method start: startpc %0h, tohostAddr %0h, fromhostAddr %0h",
|
||||
cur_cycle, startpc, tohostAddr, fromhostAddr);
|
||||
cur_cycle, startpc, tohostAddr, fromhostAddr);
|
||||
endmethod
|
||||
|
||||
// ----------------
|
||||
@@ -296,7 +296,7 @@ module mkProc (Proc_IFC);
|
||||
|
||||
interface Put hart0_put_other_req;
|
||||
method Action put (Bit #(4) req);
|
||||
cfg_verbosity <= req;
|
||||
cfg_verbosity <= req;
|
||||
endmethod
|
||||
endinterface
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
|
||||
// ================================================================
|
||||
// Notes on 'reset'
|
||||
|
||||
|
||||
// This module's default reset (Verilog RST_N) is a
|
||||
// 'non-debug-module reset', or 'ndm-reset': it resets everything
|
||||
// in mkCoreW other than the optional RISC-V Debug Module (DM).
|
||||
@@ -184,18 +184,18 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
rg_hart0_reset_delay <= fromInteger (hart_reset_duration + 200); // NOTE: heuristic
|
||||
|
||||
$display ("%0d: %m.rl_dm_hart0_reset: asserting hart0 reset for %0d cycles",
|
||||
cur_cycle, hart_reset_duration);
|
||||
cur_cycle, hart_reset_duration);
|
||||
endrule
|
||||
|
||||
rule rl_dm_hart0_reset_wait (rg_hart0_reset_delay != 0);
|
||||
if (rg_hart0_reset_delay == 1) begin
|
||||
let pc = soc_map_struct.pc_reset_value;
|
||||
proc.start (pc, rg_tohost_addr, rg_fromhost_addr);
|
||||
let pc = soc_map_struct.pc_reset_value;
|
||||
proc.start (pc, rg_tohost_addr, rg_fromhost_addr);
|
||||
|
||||
Bool is_running = True;
|
||||
debug_module.hart0_reset_client.response.put (is_running);
|
||||
$display ("%0d: %m.rl_dm_hart0_reset_wait: proc.start (pc %0h, tohostAddr %0h, fromhostAddr %0h",
|
||||
cur_cycle, pc, rg_tohost_addr, rg_fromhost_addr);
|
||||
Bool is_running = True;
|
||||
debug_module.hart0_reset_client.response.put (is_running);
|
||||
$display ("%0d: %m.rl_dm_hart0_reset_wait: proc.start (pc %0h, tohostAddr %0h, fromhostAddr %0h",
|
||||
cur_cycle, pc, rg_tohost_addr, rg_fromhost_addr);
|
||||
end
|
||||
rg_hart0_reset_delay <= rg_hart0_reset_delay - 1;
|
||||
endrule
|
||||
@@ -364,7 +364,7 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
|
||||
method Action start (Bit #(64) tohost_addr, Bit #(64) fromhost_addr);
|
||||
plic.set_addr_map (zeroExtend (soc_map.m_plic_addr_base),
|
||||
zeroExtend (soc_map.m_plic_addr_lim));
|
||||
zeroExtend (soc_map.m_plic_addr_lim));
|
||||
|
||||
let pc = soc_map_struct.pc_reset_value;
|
||||
proc.start (pc, tohost_addr, fromhost_addr);
|
||||
@@ -376,7 +376,7 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
`endif
|
||||
|
||||
$display ("%0d: %m.method start: proc.start (pc %0h, tohostAddr %0h, fromhostAddr %0h)",
|
||||
cur_cycle, pc, tohost_addr, fromhost_addr);
|
||||
cur_cycle, pc, tohost_addr, fromhost_addr);
|
||||
endmethod
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
@@ -464,11 +464,11 @@ Slave_Num_2x3 llc_slave_num = 2; // Normal cached memory (connects to co
|
||||
// Specialization of parameterized AXI4 fabric for 2x3 Core fabric
|
||||
|
||||
typedef AXI4_Fabric_IFC #(Num_Masters_2x3,
|
||||
Num_Slaves_2x3,
|
||||
Wd_Id,
|
||||
Wd_Addr,
|
||||
Wd_Data,
|
||||
Wd_User) Fabric_2x3_IFC;
|
||||
Num_Slaves_2x3,
|
||||
Wd_Id,
|
||||
Wd_Addr,
|
||||
Wd_Data,
|
||||
Wd_User) Fabric_2x3_IFC;
|
||||
|
||||
// ----------------
|
||||
|
||||
@@ -484,15 +484,15 @@ module mkFabric_2x3 (Fabric_2x3_IFC);
|
||||
|
||||
function Tuple2 #(Bool, Slave_Num_2x3) fn_addr_to_slave_num_2x3 (Fabric_Addr addr);
|
||||
if ( (soc_map.m_mem0_controller_addr_base <= addr)
|
||||
&& (addr < soc_map.m_mem0_controller_addr_lim))
|
||||
return tuple2 (True, llc_slave_num);
|
||||
&& (addr < soc_map.m_mem0_controller_addr_lim))
|
||||
return tuple2 (True, llc_slave_num);
|
||||
|
||||
else if ( (soc_map.m_plic_addr_base <= addr)
|
||||
&& (addr < soc_map.m_plic_addr_lim))
|
||||
return tuple2 (True, plic_slave_num);
|
||||
&& (addr < soc_map.m_plic_addr_lim))
|
||||
return tuple2 (True, plic_slave_num);
|
||||
|
||||
else
|
||||
return tuple2 (True, default_slave_num);
|
||||
return tuple2 (True, default_slave_num);
|
||||
endfunction
|
||||
|
||||
AXI4_Fabric_IFC #(Num_Masters_2x3, Num_Slaves_2x3, Wd_Id, Wd_Addr, Wd_Data, Wd_User)
|
||||
|
||||
@@ -86,14 +86,14 @@ module mkTV_Encode (TV_Encode_IFC);
|
||||
// v_f_cpu_ins are merged in program order (using serialnum)
|
||||
for (Integer j = 0; j < valueOf (SupSize); j = j + 1)
|
||||
rule rl_merge_cpu_ins (tpl_1 (v_f_cpu_ins [j].first) == rg_serialnum);
|
||||
let td = tpl_2 (v_f_cpu_ins [j].first);
|
||||
v_f_cpu_ins [j].deq;
|
||||
f_merged.enq (td);
|
||||
rg_serialnum <= rg_serialnum + 1;
|
||||
let td = tpl_2 (v_f_cpu_ins [j].first);
|
||||
v_f_cpu_ins [j].deq;
|
||||
f_merged.enq (td);
|
||||
rg_serialnum <= rg_serialnum + 1;
|
||||
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: %m.rl_merge_cpu_in [%0d]: serialnum = %0d", cur_cycle, j, rg_serialnum);
|
||||
end
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: %m.rl_merge_cpu_in [%0d]: serialnum = %0d", cur_cycle, j, rg_serialnum);
|
||||
end
|
||||
endrule
|
||||
|
||||
// f_dm_ins is merged in at any time
|
||||
@@ -103,7 +103,7 @@ module mkTV_Encode (TV_Encode_IFC);
|
||||
f_merged.enq (td);
|
||||
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: %m.rl_merge_dm_in", cur_cycle);
|
||||
$display ("%0d: %m.rl_merge_dm_in", cur_cycle);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -231,7 +231,7 @@ module mkTV_Encode (TV_Encode_IFC);
|
||||
f_out.enq (tuple2 (nnN, xN));
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.rl_log_trace_OTHER, pc = %0h", cur_cycle, td.pc);
|
||||
$display ("%0d: %m.rl_log_trace_OTHER, pc = %0h", cur_cycle, td.pc);
|
||||
endrule
|
||||
|
||||
rule rl_log_trace_I_RD (f_merged.first.op == TRACE_I_RD);
|
||||
@@ -254,7 +254,7 @@ module mkTV_Encode (TV_Encode_IFC);
|
||||
f_out.enq (tuple2 (nnN, xN));
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.rl_log_trace_I_RD, pc = %0h", cur_cycle, td.pc);
|
||||
$display ("%0d: %m.rl_log_trace_I_RD, pc = %0h", cur_cycle, td.pc);
|
||||
endrule
|
||||
|
||||
`ifdef ISA_F
|
||||
@@ -435,7 +435,7 @@ module mkTV_Encode (TV_Encode_IFC);
|
||||
f_out.enq (tuple2 (nnN, xN));
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.rl_log_trace_AMO, pc = %0h", cur_cycle, td.pc);
|
||||
$display ("%0d: %m.rl_log_trace_AMO, pc = %0h", cur_cycle, td.pc);
|
||||
endrule
|
||||
|
||||
rule rl_log_trace_CSRRX (f_merged.first.op == TRACE_CSRRX);
|
||||
@@ -448,14 +448,14 @@ module mkTV_Encode (TV_Encode_IFC);
|
||||
match { .n3, .vb3 } = encode_reg (fv_gpr_regnum (td.rd), td.word1);
|
||||
Bool csr_written = (td.word2 [0] == 1'b1);
|
||||
match { .n4, .vb4 } = (csr_written
|
||||
? encode_reg (fv_csr_regnum (truncate (td.word3)), td.word4)
|
||||
: tuple2 (0, ?));
|
||||
? encode_reg (fv_csr_regnum (truncate (td.word3)), td.word4)
|
||||
: tuple2 (0, ?));
|
||||
`ifdef ISA_F
|
||||
// MSTATUS.FS and .SD also updated if CSR instr wrote FFLAGS, FRM or FCSR
|
||||
Bool mstatus_written = (td.word2 [1] == 1'b1);
|
||||
match { .n5, .vb5 } = (mstatus_written
|
||||
? encode_reg (fv_csr_regnum (csr_addr_mstatus), td.word5)
|
||||
: tuple2 (0, ?));
|
||||
? encode_reg (fv_csr_regnum (csr_addr_mstatus), td.word5)
|
||||
: tuple2 (0, ?));
|
||||
`endif
|
||||
match { .nN, .vbN } = encode_byte (te_op_end_group);
|
||||
|
||||
@@ -485,28 +485,28 @@ module mkTV_Encode (TV_Encode_IFC);
|
||||
CSR_Addr csr_addr_epc = csr_addr_mepc;
|
||||
CSR_Addr csr_addr_tval = csr_addr_mtval;
|
||||
if (priv == s_Priv_Mode) begin
|
||||
csr_addr_status = csr_addr_sstatus;
|
||||
csr_addr_cause = csr_addr_scause;
|
||||
csr_addr_epc = csr_addr_sepc;
|
||||
csr_addr_tval = csr_addr_stval;
|
||||
csr_addr_status = csr_addr_sstatus;
|
||||
csr_addr_cause = csr_addr_scause;
|
||||
csr_addr_epc = csr_addr_sepc;
|
||||
csr_addr_tval = csr_addr_stval;
|
||||
end
|
||||
else if (priv == u_Priv_Mode) begin
|
||||
csr_addr_status = csr_addr_ustatus;
|
||||
csr_addr_cause = csr_addr_ucause;
|
||||
csr_addr_epc = csr_addr_uepc;
|
||||
csr_addr_tval = csr_addr_utval;
|
||||
csr_addr_status = csr_addr_ustatus;
|
||||
csr_addr_cause = csr_addr_ucause;
|
||||
csr_addr_epc = csr_addr_uepc;
|
||||
csr_addr_tval = csr_addr_utval;
|
||||
end
|
||||
|
||||
// Omit the instruction if cause is instruction fault since the instruction is then bogus
|
||||
Bool is_instr_fault = ( (truncate (td.word2) == exc_code_INSTR_ACCESS_FAULT)
|
||||
|| (truncate (td.word2) == exc_code_INSTR_PAGE_FAULT));
|
||||
|| (truncate (td.word2) == exc_code_INSTR_PAGE_FAULT));
|
||||
|
||||
// Encode components of td into byte vecs
|
||||
match { .n0, .vb0 } = encode_byte (te_op_begin_group);
|
||||
match { .n1, .vb1 } = encode_pc (td.pc);
|
||||
match { .n2, .vb2 } = (is_instr_fault
|
||||
? tuple2 (0, ?)
|
||||
: encode_instr (td.instr_sz, td.instr));
|
||||
? tuple2 (0, ?)
|
||||
: encode_instr (td.instr_sz, td.instr));
|
||||
match { .n3, .vb3 } = encode_priv (td.rd);
|
||||
match { .n4, .vb4 } = encode_reg (fv_csr_regnum (csr_addr_status), td.word1);
|
||||
match { .n5, .vb5 } = encode_reg (fv_csr_regnum (csr_addr_cause), td.word2);
|
||||
@@ -538,16 +538,16 @@ module mkTV_Encode (TV_Encode_IFC);
|
||||
CSR_Addr csr_addr_epc = csr_addr_mepc;
|
||||
CSR_Addr csr_addr_tval = csr_addr_mtval;
|
||||
if (priv == s_Priv_Mode) begin
|
||||
csr_addr_status = csr_addr_sstatus;
|
||||
csr_addr_cause = csr_addr_scause;
|
||||
csr_addr_epc = csr_addr_sepc;
|
||||
csr_addr_tval = csr_addr_stval;
|
||||
csr_addr_status = csr_addr_sstatus;
|
||||
csr_addr_cause = csr_addr_scause;
|
||||
csr_addr_epc = csr_addr_sepc;
|
||||
csr_addr_tval = csr_addr_stval;
|
||||
end
|
||||
else if (priv == u_Priv_Mode) begin
|
||||
csr_addr_status = csr_addr_ustatus;
|
||||
csr_addr_cause = csr_addr_ucause;
|
||||
csr_addr_epc = csr_addr_uepc;
|
||||
csr_addr_tval = csr_addr_utval;
|
||||
csr_addr_status = csr_addr_ustatus;
|
||||
csr_addr_cause = csr_addr_ucause;
|
||||
csr_addr_epc = csr_addr_uepc;
|
||||
csr_addr_tval = csr_addr_utval;
|
||||
end
|
||||
|
||||
// Encode components of td into byte vecs
|
||||
@@ -682,15 +682,15 @@ endfunction
|
||||
// vsubst substitutes vb1[j1:j1+j2-1] with vb2[0:j2-1]
|
||||
|
||||
function Tuple2 #(Bit #(32),
|
||||
Vector #(TV_VB_SIZE, Byte))
|
||||
Vector #(TV_VB_SIZE, Byte))
|
||||
vsubst (Bit #(32) j1, Vector #(TV_VB_SIZE, Byte) vb1,
|
||||
Bit #(32) j2, Vector #(m, Byte) vb2);
|
||||
Bit #(32) j2, Vector #(m, Byte) vb2);
|
||||
|
||||
function Byte f (Integer j);
|
||||
Byte x = vb1 [j];
|
||||
Bit #(32) jj = fromInteger (j);
|
||||
if ((j1 <= jj) && (jj < j1 + j2))
|
||||
x = vb2 [jj - j1];
|
||||
x = vb2 [jj - j1];
|
||||
return x;
|
||||
endfunction
|
||||
|
||||
@@ -859,11 +859,11 @@ function Tuple2 #(Bit #(32), Vector #(TV_VB_SIZE, Byte)) encode_stval (MemReqSiz
|
||||
Vector #(TV_VB_SIZE, Byte) vb = newVector;
|
||||
vb [0] = te_op_addl_state;
|
||||
vb [1] = case (mem_req_size)
|
||||
f3_SIZE_B: te_op_addl_state_data8;
|
||||
f3_SIZE_H: te_op_addl_state_data16;
|
||||
f3_SIZE_W: te_op_addl_state_data32;
|
||||
f3_SIZE_D: te_op_addl_state_data64;
|
||||
endcase;
|
||||
f3_SIZE_B: te_op_addl_state_data8;
|
||||
f3_SIZE_H: te_op_addl_state_data16;
|
||||
f3_SIZE_W: te_op_addl_state_data32;
|
||||
f3_SIZE_D: te_op_addl_state_data64;
|
||||
endcase;
|
||||
vb [2] = word [7:0];
|
||||
vb [3] = word [15:8];
|
||||
vb [4] = word [23:16];
|
||||
@@ -883,11 +883,11 @@ function Tuple2 #(Bit #(32), Vector #(TV_VB_SIZE, Byte)) encode_fstval (MemReqSi
|
||||
Vector #(TV_VB_SIZE, Byte) vb = newVector;
|
||||
vb [0] = te_op_addl_state;
|
||||
vb [1] = case (mem_req_size)
|
||||
f3_SIZE_B: te_op_addl_state_data8; // not possible
|
||||
f3_SIZE_H: te_op_addl_state_data16; // not possible
|
||||
f3_SIZE_W: te_op_addl_state_data32;
|
||||
f3_SIZE_D: te_op_addl_state_data64;
|
||||
endcase;
|
||||
f3_SIZE_B: te_op_addl_state_data8; // not possible
|
||||
f3_SIZE_H: te_op_addl_state_data16; // not possible
|
||||
f3_SIZE_W: te_op_addl_state_data32;
|
||||
f3_SIZE_D: te_op_addl_state_data64;
|
||||
endcase;
|
||||
vb [2] = word [7:0];
|
||||
vb [3] = word [15:8];
|
||||
vb [4] = word [23:16];
|
||||
|
||||
@@ -81,23 +81,23 @@ module mkDM_Mem_Tap (DM_Mem_Tap_IFC);
|
||||
|
||||
case (wr_data.wstrb)
|
||||
`ifdef FABRIC64
|
||||
'hFF: begin sh= 0; mask = 'hFFFF_FFFF_FFFF_FFFF; sz=f3_SIZE_D; end
|
||||
'hF0: begin sh=32; mask = 'hFFFF_FFFF; sz=f3_SIZE_W; end
|
||||
'hC0: begin sh=48; mask = 'hFFFF; sz=f3_SIZE_H; end
|
||||
'h30: begin sh=32; mask = 'hFFFF; sz=f3_SIZE_H; end
|
||||
'h80: begin sh=56; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
'h40: begin sh=48; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
'h20: begin sh=40; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
'h10: begin sh=32; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
'hFF: begin sh= 0; mask = 'hFFFF_FFFF_FFFF_FFFF; sz=f3_SIZE_D; end
|
||||
'hF0: begin sh=32; mask = 'hFFFF_FFFF; sz=f3_SIZE_W; end
|
||||
'hC0: begin sh=48; mask = 'hFFFF; sz=f3_SIZE_H; end
|
||||
'h30: begin sh=32; mask = 'hFFFF; sz=f3_SIZE_H; end
|
||||
'h80: begin sh=56; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
'h40: begin sh=48; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
'h20: begin sh=40; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
'h10: begin sh=32; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
`endif
|
||||
'hF: begin sh= 0; mask = 'hFFFF_FFFF; sz=f3_SIZE_W; end
|
||||
'hC: begin sh=16; mask = 'hFFFF; sz=f3_SIZE_H; end
|
||||
'h3: begin sh= 0; mask = 'hFFFF; sz=f3_SIZE_H; end
|
||||
'h8: begin sh=24; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
'h4: begin sh=16; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
'h2: begin sh= 8; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
'h1: begin sh= 0; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
default: dynamicAssert(False, "mkDM_Mem_Tap: unsupported byte enables");
|
||||
'hF: begin sh= 0; mask = 'hFFFF_FFFF; sz=f3_SIZE_W; end
|
||||
'hC: begin sh=16; mask = 'hFFFF; sz=f3_SIZE_H; end
|
||||
'h3: begin sh= 0; mask = 'hFFFF; sz=f3_SIZE_H; end
|
||||
'h8: begin sh=24; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
'h4: begin sh=16; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
'h2: begin sh= 8; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
'h1: begin sh= 0; mask = 'hFF; sz=f3_SIZE_B; end
|
||||
default: dynamicAssert(False, "mkDM_Mem_Tap: unsupported byte enables");
|
||||
endcase
|
||||
paddr = zeroExtend (wr_addr.awaddr);
|
||||
stval = ((zeroExtend (wr_data.wdata) >> sh) & mask);
|
||||
@@ -150,9 +150,9 @@ module mkDM_GPR_Tap (DM_GPR_Tap_IFC);
|
||||
|
||||
// Snoop writes and send trace data to TV
|
||||
if (req.write) begin
|
||||
Trace_Data td;
|
||||
td = mkTrace_GPR_WRITE (req.address, req.data);
|
||||
f_trace_data.enq (td);
|
||||
Trace_Data td;
|
||||
td = mkTrace_GPR_WRITE (req.address, req.data);
|
||||
f_trace_data.enq (td);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -192,9 +192,9 @@ module mkDM_FPR_Tap (DM_FPR_Tap_IFC);
|
||||
|
||||
// Snoop writes and send trace data to TV
|
||||
if (req.write) begin
|
||||
Trace_Data td;
|
||||
td = mkTrace_FPR_WRITE (req.address, req.data);
|
||||
f_trace_data.enq (td);
|
||||
Trace_Data td;
|
||||
td = mkTrace_FPR_WRITE (req.address, req.data);
|
||||
f_trace_data.enq (td);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -234,8 +234,8 @@ module mkDM_CSR_Tap (DM_CSR_Tap_IFC);
|
||||
|
||||
// Snoop writes and send trace data to TV
|
||||
if (req.write) begin
|
||||
Trace_Data td = mkTrace_CSR_WRITE (req.address, req.data);
|
||||
f_trace_data.enq (td);
|
||||
Trace_Data td = mkTrace_CSR_WRITE (req.address, req.data);
|
||||
f_trace_data.enq (td);
|
||||
end
|
||||
endrule
|
||||
|
||||
|
||||
@@ -60,168 +60,168 @@ module mkTrace_Data2_to_Trace_Data (Trace_Data2_to_Trace_Data_IFC);
|
||||
|
||||
function ActionValue #(Tuple2 #(Bit #(64), Trace_Data)) fav_td2_to_td (Trace_Data2 td2);
|
||||
actionvalue
|
||||
let serial_num = td2.serial_num;
|
||||
Trace_Data td = ?;
|
||||
ISize isize = ((td2.orig_inst [1:0] == 2'b11) ? ISIZE32BIT : ISIZE16BIT);
|
||||
Addr fall_thru_PC = td2.pc + ((td2.orig_inst [1:0] == 2'b11) ? 4 : 2);
|
||||
let serial_num = td2.serial_num;
|
||||
Trace_Data td = ?;
|
||||
ISize isize = ((td2.orig_inst [1:0] == 2'b11) ? ISIZE32BIT : ISIZE16BIT);
|
||||
Addr fall_thru_PC = td2.pc + ((td2.orig_inst [1:0] == 2'b11) ? 4 : 2);
|
||||
|
||||
Bit #(3) st_funct3 = (td2.store_data_BE [7] ? 3'b_011 // Doubleword
|
||||
: (td2.store_data_BE [3] ? 3'b_010 // Word
|
||||
: (td2.store_data_BE [1] ? 3'b_001 // HalfWord
|
||||
: 3'b000))); // Byte
|
||||
Bit #(3) st_funct3 = (td2.store_data_BE [7] ? 3'b_011 // Doubleword
|
||||
: (td2.store_data_BE [3] ? 3'b_010 // Word
|
||||
: (td2.store_data_BE [1] ? 3'b_001 // HalfWord
|
||||
: 3'b000))); // Byte
|
||||
|
||||
Bit #(5) gpr_rd = 0;
|
||||
if (td2.dst matches tagged Valid (tagged Gpr .r)) gpr_rd = r;
|
||||
Bit #(5) gpr_rd = 0;
|
||||
if (td2.dst matches tagged Valid (tagged Gpr .r)) gpr_rd = r;
|
||||
|
||||
if (serial_num == 0)
|
||||
td = mkTrace_RESET;
|
||||
if (serial_num == 0)
|
||||
td = mkTrace_RESET;
|
||||
|
||||
else if (td2.maybe_csr_upd matches tagged Valid { .csr_addr, .csr_value })
|
||||
td = mkTrace_CSR_WRITE (csr_addr, csr_value);
|
||||
else if (td2.maybe_csr_upd matches tagged Valid { .csr_addr, .csr_value })
|
||||
td = mkTrace_CSR_WRITE (csr_addr, csr_value);
|
||||
|
||||
else if (isValid (td2.trap))
|
||||
td = mkTrace_TRAP (td2.tvec,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
td2.prv,
|
||||
td2.status,
|
||||
td2.cause,
|
||||
td2.epc,
|
||||
td2.tval);
|
||||
else if (isValid (td2.trap))
|
||||
td = mkTrace_TRAP (td2.tvec,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
td2.prv,
|
||||
td2.status,
|
||||
td2.cause,
|
||||
td2.epc,
|
||||
td2.tval);
|
||||
|
||||
else if (td2.ppc_vaddr_csrData matches tagged PPC .target_addr
|
||||
&&& (td2.iType == Br))
|
||||
td = mkTrace_OTHER (target_addr, isize, td2.orig_inst);
|
||||
else if (td2.ppc_vaddr_csrData matches tagged PPC .target_addr
|
||||
&&& (td2.iType == Br))
|
||||
td = mkTrace_OTHER (target_addr, isize, td2.orig_inst);
|
||||
|
||||
else if (td2.ppc_vaddr_csrData matches tagged PPC .target_addr
|
||||
&&& ( (td2.iType == J)
|
||||
|| (td2.iType == Jr)))
|
||||
td = mkTrace_I_RD (target_addr,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
td2.dst_data); // return-pc
|
||||
else if (td2.ppc_vaddr_csrData matches tagged PPC .target_addr
|
||||
&&& ( (td2.iType == J)
|
||||
|| (td2.iType == Jr)))
|
||||
td = mkTrace_I_RD (target_addr,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
td2.dst_data); // return-pc
|
||||
|
||||
else if ( (td2.iType == Alu)
|
||||
|| (td2.iType == Auipc))
|
||||
td = mkTrace_I_RD (fall_thru_PC,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
td2.dst_data); // rd_val
|
||||
else if ( (td2.iType == Alu)
|
||||
|| (td2.iType == Auipc))
|
||||
td = mkTrace_I_RD (fall_thru_PC,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
td2.dst_data); // rd_val
|
||||
|
||||
else if (td2.dst matches tagged Valid (tagged Fpu .fpr_rd)
|
||||
&&& (td2.iType == Fpu))
|
||||
td = mkTrace_F_FRD (fall_thru_PC,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
fpr_rd,
|
||||
td2.dst_data, // rdval
|
||||
td2.fflags,
|
||||
td2.mstatus); // [FX] updated
|
||||
else if (td2.dst matches tagged Valid (tagged Fpu .fpr_rd)
|
||||
&&& (td2.iType == Fpu))
|
||||
td = mkTrace_F_FRD (fall_thru_PC,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
fpr_rd,
|
||||
td2.dst_data, // rdval
|
||||
td2.fflags,
|
||||
td2.mstatus); // [FX] updated
|
||||
|
||||
else if (td2.iType == Fpu)
|
||||
td = mkTrace_F_GRD (fall_thru_PC,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
td2.dst_data, // rdval
|
||||
td2.fflags,
|
||||
td2.mstatus); // [FX] updated
|
||||
else if (td2.iType == Fpu)
|
||||
td = mkTrace_F_GRD (fall_thru_PC,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
td2.dst_data, // rdval
|
||||
td2.fflags,
|
||||
td2.mstatus); // [FX] updated
|
||||
|
||||
else if (td2.ppc_vaddr_csrData matches tagged VAddr .eaddr
|
||||
&&& td2.dst matches tagged Valid (tagged Fpu .fpr_rd)
|
||||
&&& (td2.iType == Ld))
|
||||
td = mkTrace_F_LOAD (fall_thru_PC,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
fpr_rd,
|
||||
td2.dst_data, // rd_val
|
||||
eaddr,
|
||||
td2.mstatus);
|
||||
else if (td2.ppc_vaddr_csrData matches tagged VAddr .eaddr
|
||||
&&& td2.dst matches tagged Valid (tagged Fpu .fpr_rd)
|
||||
&&& (td2.iType == Ld))
|
||||
td = mkTrace_F_LOAD (fall_thru_PC,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
fpr_rd,
|
||||
td2.dst_data, // rd_val
|
||||
eaddr,
|
||||
td2.mstatus);
|
||||
|
||||
else if (td2.ppc_vaddr_csrData matches tagged VAddr .eaddr
|
||||
&&& (td2.iType == Ld))
|
||||
td = mkTrace_I_LOAD (fall_thru_PC,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
td2.dst_data, // rd_val
|
||||
eaddr);
|
||||
else if (td2.ppc_vaddr_csrData matches tagged VAddr .eaddr
|
||||
&&& (td2.iType == Ld))
|
||||
td = mkTrace_I_LOAD (fall_thru_PC,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
td2.dst_data, // rd_val
|
||||
eaddr);
|
||||
|
||||
else if (td2.ppc_vaddr_csrData matches tagged VAddr .eaddr
|
||||
&&& (td2.iType == St))
|
||||
td = mkTrace_I_STORE (fall_thru_PC,
|
||||
st_funct3,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
td2.store_data, // rs2_val
|
||||
eaddr);
|
||||
else if (td2.ppc_vaddr_csrData matches tagged VAddr .eaddr
|
||||
&&& (td2.iType == St))
|
||||
td = mkTrace_I_STORE (fall_thru_PC,
|
||||
st_funct3,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
td2.store_data, // rs2_val
|
||||
eaddr);
|
||||
|
||||
else if (td2.ppc_vaddr_csrData matches tagged CSRData .csr_data
|
||||
&&& (td2.iType == Csr))
|
||||
begin
|
||||
Bit #(3) funct3 = td2.orig_inst [14:12];
|
||||
Bit #(5) rs1_or_imm = td2.orig_inst [19:15];
|
||||
Bool csr_valid = False;
|
||||
CSR_Addr csr_addr = 0;
|
||||
if (td2.csr matches tagged Valid .c) begin
|
||||
csr_addr = pack (c);
|
||||
csr_valid = ( (funct3 [1:0] == 2'b01) // CSRRW, CSRRWI
|
||||
|| ( ( (funct3 [1:0] == 2'b10) // CSRRS, CSRRSI
|
||||
|| (funct3 [1:0] == 2'b11)) // CSRRC, CSRRCI
|
||||
&& (rs1_or_imm != 0)));
|
||||
end
|
||||
td = mkTrace_CSRRX (fall_thru_PC,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
td2.dst_data, // rdval
|
||||
csr_valid,
|
||||
csr_addr,
|
||||
csr_data,
|
||||
// For CSR writes to FFLAGS/FRM/FCSR, also changes MSTATUS
|
||||
td2.will_dirty_fpu_state,
|
||||
td2.mstatus);
|
||||
end
|
||||
else if (td2.ppc_vaddr_csrData matches tagged CSRData .csr_data
|
||||
&&& (td2.iType == Csr))
|
||||
begin
|
||||
Bit #(3) funct3 = td2.orig_inst [14:12];
|
||||
Bit #(5) rs1_or_imm = td2.orig_inst [19:15];
|
||||
Bool csr_valid = False;
|
||||
CSR_Addr csr_addr = 0;
|
||||
if (td2.csr matches tagged Valid .c) begin
|
||||
csr_addr = pack (c);
|
||||
csr_valid = ( (funct3 [1:0] == 2'b01) // CSRRW, CSRRWI
|
||||
|| ( ( (funct3 [1:0] == 2'b10) // CSRRS, CSRRSI
|
||||
|| (funct3 [1:0] == 2'b11)) // CSRRC, CSRRCI
|
||||
&& (rs1_or_imm != 0)));
|
||||
end
|
||||
td = mkTrace_CSRRX (fall_thru_PC,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
td2.dst_data, // rdval
|
||||
csr_valid,
|
||||
csr_addr,
|
||||
csr_data,
|
||||
// For CSR writes to FFLAGS/FRM/FCSR, also changes MSTATUS
|
||||
td2.will_dirty_fpu_state,
|
||||
td2.mstatus);
|
||||
end
|
||||
|
||||
else if ( (td2.iType == Mret)
|
||||
|| (td2.iType == Sret))
|
||||
td = mkTrace_RET (td2.pc, isize, td2.orig_inst, td2.prv, td2.status);
|
||||
else if ( (td2.iType == Mret)
|
||||
|| (td2.iType == Sret))
|
||||
td = mkTrace_RET (td2.pc, isize, td2.orig_inst, td2.prv, td2.status);
|
||||
|
||||
else if ( (td2.iType == Fence)
|
||||
|| (td2.iType == FenceI)
|
||||
|| (td2.iType == SFence)
|
||||
|| (td2.iType == Ecall) // Handled by TRAP above?
|
||||
|| (td2.iType == Ebreak)) // Handled by TRAP above?
|
||||
td = mkTrace_OTHER (fall_thru_PC, isize, td2.orig_inst);
|
||||
else if ( (td2.iType == Fence)
|
||||
|| (td2.iType == FenceI)
|
||||
|| (td2.iType == SFence)
|
||||
|| (td2.iType == Ecall) // Handled by TRAP above?
|
||||
|| (td2.iType == Ebreak)) // Handled by TRAP above?
|
||||
td = mkTrace_OTHER (fall_thru_PC, isize, td2.orig_inst);
|
||||
|
||||
else if (td2.ppc_vaddr_csrData matches tagged VAddr .eaddr
|
||||
&&& ( (td2.iType == Amo)
|
||||
|| (td2.iType == Lr)
|
||||
|| (td2.iType == Sc)))
|
||||
td = mkTrace_AMO (fall_thru_PC,
|
||||
st_funct3,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
td2.dst_data, // rd_val
|
||||
td2.store_data, // rs2_val
|
||||
eaddr);
|
||||
else if (td2.ppc_vaddr_csrData matches tagged VAddr .eaddr
|
||||
&&& ( (td2.iType == Amo)
|
||||
|| (td2.iType == Lr)
|
||||
|| (td2.iType == Sc)))
|
||||
td = mkTrace_AMO (fall_thru_PC,
|
||||
st_funct3,
|
||||
isize,
|
||||
td2.orig_inst,
|
||||
gpr_rd,
|
||||
td2.dst_data, // rd_val
|
||||
td2.store_data, // rs2_val
|
||||
eaddr);
|
||||
|
||||
else if ( (td2.iType == Unsupported)
|
||||
|| (td2.iType == Nop)
|
||||
|| (td2.iType == Interrupt))
|
||||
td = mkTrace_OTHER (fall_thru_PC, isize, td2.orig_inst);
|
||||
else if ( (td2.iType == Unsupported)
|
||||
|| (td2.iType == Nop)
|
||||
|| (td2.iType == Interrupt))
|
||||
td = mkTrace_OTHER (fall_thru_PC, isize, td2.orig_inst);
|
||||
|
||||
else begin
|
||||
if (verbosity > 0) begin
|
||||
$display (" fav_td2_to_td: TBD: Unknown iType: Using mkTrace_OTHER for now");
|
||||
$display (" ", fshow (td2));
|
||||
end
|
||||
td = mkTrace_OTHER (fall_thru_PC, isize, td2.orig_inst);
|
||||
end
|
||||
return tuple2 (serial_num, td);
|
||||
else begin
|
||||
if (verbosity > 0) begin
|
||||
$display (" fav_td2_to_td: TBD: Unknown iType: Using mkTrace_OTHER for now");
|
||||
$display (" ", fshow (td2));
|
||||
end
|
||||
td = mkTrace_OTHER (fall_thru_PC, isize, td2.orig_inst);
|
||||
end
|
||||
return tuple2 (serial_num, td);
|
||||
endactionvalue
|
||||
endfunction
|
||||
|
||||
@@ -232,9 +232,9 @@ module mkTrace_Data2_to_Trace_Data (Trace_Data2_to_Trace_Data_IFC);
|
||||
Trace_Data2 td2 <- pop (f_in);
|
||||
|
||||
if (verbosity > 1)
|
||||
$display ("%0d: %m.rl_td2_to_td: serial_num:%0d PC:0x%0h instr:0x%08h",
|
||||
cur_cycle, td2.serial_num, td2.pc, td2.orig_inst,
|
||||
" iType:", fshow (td2.iType));
|
||||
$display ("%0d: %m.rl_td2_to_td: serial_num:%0d PC:0x%0h instr:0x%08h",
|
||||
cur_cycle, td2.serial_num, td2.pc, td2.orig_inst,
|
||||
" iType:", fshow (td2.iType));
|
||||
|
||||
match { .serial_num, .td } <- fav_td2_to_td (td2);
|
||||
f_out.enq (tuple2 (serial_num, td));
|
||||
|
||||
@@ -95,30 +95,30 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
Bit #(4) abstractcs_datacount = ((xlen == 32) ? 1 : 2);
|
||||
|
||||
DM_Word virt_rg_abstractcs = {3'b0,
|
||||
abstractcs_progbufsize,
|
||||
11'b0,
|
||||
pack (rg_abstractcs_busy),
|
||||
1'b0,
|
||||
pack (rg_abstractcs_cmderr),
|
||||
4'b0,
|
||||
abstractcs_datacount};
|
||||
abstractcs_progbufsize,
|
||||
11'b0,
|
||||
pack (rg_abstractcs_busy),
|
||||
1'b0,
|
||||
pack (rg_abstractcs_cmderr),
|
||||
4'b0,
|
||||
abstractcs_datacount};
|
||||
|
||||
function Action fa_rg_abstractcs_write (DM_Word dm_word);
|
||||
action
|
||||
if (rg_abstractcs_busy) begin
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_BUSY;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [abstractcs] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" DM is busy with a previous abstract command");
|
||||
end
|
||||
else if (fn_abstractcs_cmderr (dm_word) != DM_ABSTRACTCS_CMDERR_NONE) begin
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_NONE;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write [abstractcs]: clearing cmderr", cur_cycle);
|
||||
end
|
||||
else begin
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write [abstractcs]: cmderr unchanged", cur_cycle);
|
||||
end
|
||||
if (rg_abstractcs_busy) begin
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_BUSY;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [abstractcs] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" DM is busy with a previous abstract command");
|
||||
end
|
||||
else if (fn_abstractcs_cmderr (dm_word) != DM_ABSTRACTCS_CMDERR_NONE) begin
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_NONE;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write [abstractcs]: clearing cmderr", cur_cycle);
|
||||
end
|
||||
else begin
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write [abstractcs]: cmderr unchanged", cur_cycle);
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -144,78 +144,78 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
|
||||
function Action fa_rg_command_write (DM_Word dm_word);
|
||||
action
|
||||
// TODO: check that CPU is halted, else set cmderr = DM_ABSTRACTCS_CMDERR_HALT_RESUME
|
||||
// TODO: check that CPU is halted, else set cmderr = DM_ABSTRACTCS_CMDERR_HALT_RESUME
|
||||
|
||||
DM_abstractcs_cmderr cmderr = rg_abstractcs_cmderr;
|
||||
let size = fn_command_access_reg_size (dm_word);
|
||||
DM_abstractcs_cmderr cmderr = rg_abstractcs_cmderr;
|
||||
let size = fn_command_access_reg_size (dm_word);
|
||||
|
||||
// Ignore if 'cmderr' is non-zero
|
||||
if (cmderr != DM_ABSTRACTCS_CMDERR_NONE) begin
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" Ignoring since 'cmderr' is 0x%0h", cmderr);
|
||||
end
|
||||
else begin
|
||||
if (rg_abstractcs_busy) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_BUSY;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" DM is busy with a previous abstract command");
|
||||
end
|
||||
// Ignore if 'cmderr' is non-zero
|
||||
if (cmderr != DM_ABSTRACTCS_CMDERR_NONE) begin
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" Ignoring since 'cmderr' is 0x%0h", cmderr);
|
||||
end
|
||||
else begin
|
||||
if (rg_abstractcs_busy) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_BUSY;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" DM is busy with a previous abstract command");
|
||||
end
|
||||
|
||||
// Only 'Access Reg' cmdtype is supported
|
||||
else if (fn_command_cmdtype (dm_word) != DM_COMMAND_CMDTYPE_ACCESS_REG) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" ", fshow (fn_command_cmdtype (dm_word)), " not supported");
|
||||
end
|
||||
// Only 'Access Reg' cmdtype is supported
|
||||
else if (fn_command_cmdtype (dm_word) != DM_COMMAND_CMDTYPE_ACCESS_REG) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" ", fshow (fn_command_cmdtype (dm_word)), " not supported");
|
||||
end
|
||||
|
||||
`ifdef RV32
|
||||
// Only lower 32-bit access is supported
|
||||
else if (size != DM_COMMAND_ACCESS_REG_SIZE_LOWER32) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, ",
|
||||
fshow (fn_command_access_reg_size (dm_word)), " not supported in RV32 mode");
|
||||
end
|
||||
// Only lower 32-bit access is supported
|
||||
else if (size != DM_COMMAND_ACCESS_REG_SIZE_LOWER32) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, ",
|
||||
fshow (fn_command_access_reg_size (dm_word)), " not supported in RV32 mode");
|
||||
end
|
||||
`endif
|
||||
`ifdef RV64
|
||||
// Only lower 32-bit and 64-bit access is supported
|
||||
else if (size != DM_COMMAND_ACCESS_REG_SIZE_LOWER64)
|
||||
begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, ",
|
||||
fshow (fn_command_access_reg_size (dm_word)), " not supported in RV64 mode");
|
||||
end
|
||||
// Only lower 32-bit and 64-bit access is supported
|
||||
else if (size != DM_COMMAND_ACCESS_REG_SIZE_LOWER64)
|
||||
begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, ",
|
||||
fshow (fn_command_access_reg_size (dm_word)), " not supported in RV64 mode");
|
||||
end
|
||||
`endif
|
||||
|
||||
// 'postexec' is not supported
|
||||
else if (fn_command_access_reg_postexec (dm_word) == True) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, postexec not supported");
|
||||
end
|
||||
// 'postexec' is not supported
|
||||
else if (fn_command_access_reg_postexec (dm_word) == True) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, postexec not supported");
|
||||
end
|
||||
|
||||
// non-'transfer' is not supported
|
||||
else if (fn_command_access_reg_transfer (dm_word) == False) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, no-transfer not supported");
|
||||
end
|
||||
// non-'transfer' is not supported
|
||||
else if (fn_command_access_reg_transfer (dm_word) == False) begin
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: ERROR", cur_cycle, dm_word);
|
||||
$display (" For DM_COMMAND_CMDTYPE_ACCESS_REG, no-transfer not supported");
|
||||
end
|
||||
|
||||
else begin
|
||||
Bool is_write = fn_command_access_reg_write (dm_word);
|
||||
Bit #(13) regno = truncate (fn_command_access_reg_regno (dm_word));
|
||||
else begin
|
||||
Bool is_write = fn_command_access_reg_write (dm_word);
|
||||
Bit #(13) regno = truncate (fn_command_access_reg_regno (dm_word));
|
||||
|
||||
rg_command_access_reg_write <= is_write;
|
||||
rg_command_access_reg_regno <= regno;
|
||||
rg_abstractcs_busy <= True;
|
||||
rg_start_reg_access <= True;
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NONE;
|
||||
rg_command_access_reg_write <= is_write;
|
||||
rg_command_access_reg_regno <= regno;
|
||||
rg_abstractcs_busy <= True;
|
||||
rg_start_reg_access <= True;
|
||||
cmderr = DM_ABSTRACTCS_CMDERR_NONE;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write: [command] <= 0x%08h: OKAY", cur_cycle, dm_word);
|
||||
end
|
||||
rg_abstractcs_cmderr <= cmderr;
|
||||
end
|
||||
end
|
||||
rg_abstractcs_cmderr <= cmderr;
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -223,14 +223,14 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Register reads and writes
|
||||
|
||||
Bool is_csr = ( (fromInteger (dm_command_access_reg_regno_csr_0) <= rg_command_access_reg_regno)
|
||||
&& (rg_command_access_reg_regno <= fromInteger (dm_command_access_reg_regno_csr_FFF)));
|
||||
&& (rg_command_access_reg_regno <= fromInteger (dm_command_access_reg_regno_csr_FFF)));
|
||||
|
||||
Bool is_gpr = ( (fromInteger (dm_command_access_reg_regno_gpr_0) <= rg_command_access_reg_regno)
|
||||
&& (rg_command_access_reg_regno <= fromInteger (dm_command_access_reg_regno_gpr_1F)));
|
||||
&& (rg_command_access_reg_regno <= fromInteger (dm_command_access_reg_regno_gpr_1F)));
|
||||
|
||||
`ifdef ISA_F
|
||||
Bool is_fpr = ( (fromInteger (dm_command_access_reg_regno_fpr_0) <= rg_command_access_reg_regno)
|
||||
&& (rg_command_access_reg_regno <= fromInteger (dm_command_access_reg_regno_fpr_1F)));
|
||||
&& (rg_command_access_reg_regno <= fromInteger (dm_command_access_reg_regno_fpr_1F)));
|
||||
`else
|
||||
Bool is_fpr = False;
|
||||
`endif
|
||||
@@ -243,33 +243,33 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Write CSR
|
||||
|
||||
rule rl_csr_write_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& is_csr);
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& is_csr);
|
||||
let req = DM_CPU_Req {write: True,
|
||||
address: csr_addr,
|
||||
address: csr_addr,
|
||||
`ifdef RV32
|
||||
data: rg_data0
|
||||
data: rg_data0
|
||||
`endif
|
||||
`ifdef RV64
|
||||
data: {rg_data1, rg_data0}
|
||||
data: {rg_data1, rg_data0}
|
||||
`endif
|
||||
};
|
||||
};
|
||||
f_hart0_csr_reqs.enq (req);
|
||||
rg_start_reg_access <= False;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_write_start: ", cur_cycle, fshow (req));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_write_start: ", cur_cycle, fshow (req));
|
||||
endrule
|
||||
|
||||
// ----------------
|
||||
|
||||
rule rl_csr_write_finish (rg_abstractcs_busy
|
||||
&& rg_command_access_reg_write
|
||||
&& is_csr);
|
||||
&& rg_command_access_reg_write
|
||||
&& is_csr);
|
||||
let rsp <- pop (f_hart0_csr_rsps);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_write_finish: ", cur_cycle, fshow (rsp));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_write_finish: ", cur_cycle, fshow (rsp));
|
||||
|
||||
rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME);
|
||||
rg_abstractcs_busy <= False;
|
||||
@@ -279,26 +279,26 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Read CSR
|
||||
|
||||
rule rl_csr_read_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_csr);
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_csr);
|
||||
Bit #(XLEN) data = ?;
|
||||
let req = DM_CPU_Req {write: False, address: csr_addr, data: data};
|
||||
f_hart0_csr_reqs.enq (req);
|
||||
rg_start_reg_access <= False;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_read_start: ", cur_cycle, fshow (req));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_read_start: ", cur_cycle, fshow (req));
|
||||
endrule
|
||||
|
||||
// ----------------
|
||||
|
||||
rule rl_csr_read_finish ( rg_abstractcs_busy
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_csr);
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_csr);
|
||||
let rsp <- pop (f_hart0_csr_rsps);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_read_finish: ", cur_cycle, fshow (rsp));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_csr_read_finish: ", cur_cycle, fshow (rsp));
|
||||
|
||||
rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME);
|
||||
`ifdef RV32
|
||||
@@ -315,32 +315,32 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Write GPR
|
||||
|
||||
rule rl_gpr_write_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& is_gpr);
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& is_gpr);
|
||||
let req = DM_CPU_Req {write: True,
|
||||
address: gpr_addr,
|
||||
address: gpr_addr,
|
||||
`ifdef RV32
|
||||
data: rg_data0
|
||||
data: rg_data0
|
||||
`endif
|
||||
`ifdef RV64
|
||||
data: {rg_data1, rg_data0}
|
||||
data: {rg_data1, rg_data0}
|
||||
`endif
|
||||
};
|
||||
};
|
||||
f_hart0_gpr_reqs.enq (req);
|
||||
rg_start_reg_access <= False;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_write_start: ", cur_cycle, fshow (req));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_write_start: ", cur_cycle, fshow (req));
|
||||
endrule
|
||||
|
||||
// ----------------
|
||||
|
||||
rule rl_gpr_write_finish ( rg_abstractcs_busy
|
||||
&& rg_command_access_reg_write
|
||||
&& is_gpr);
|
||||
&& rg_command_access_reg_write
|
||||
&& is_gpr);
|
||||
let rsp <- pop (f_hart0_gpr_rsps);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_write_finish: ", cur_cycle, fshow (rsp));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_write_finish: ", cur_cycle, fshow (rsp));
|
||||
|
||||
rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME);
|
||||
rg_abstractcs_busy <= False;
|
||||
@@ -350,26 +350,26 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Read GPR
|
||||
|
||||
rule rl_gpr_read_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_gpr);
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_gpr);
|
||||
Bit #(XLEN) data = ?;
|
||||
let req = DM_CPU_Req {write: False, address: gpr_addr, data: data };
|
||||
f_hart0_gpr_reqs.enq (req);
|
||||
rg_start_reg_access <= False;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_read_start: ", cur_cycle, fshow (req));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_read_start: ", cur_cycle, fshow (req));
|
||||
endrule
|
||||
|
||||
// ----------------
|
||||
|
||||
rule rl_gpr_read_finish ( rg_abstractcs_busy
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_gpr);
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_gpr);
|
||||
let rsp <- pop (f_hart0_gpr_rsps);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_read_finish: ", cur_cycle, fshow (rsp));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_gpr_read_finish: ", cur_cycle, fshow (rsp));
|
||||
|
||||
`ifdef RV32
|
||||
rg_data0 <= rsp.data;
|
||||
@@ -388,32 +388,32 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
`ifdef ISA_F
|
||||
|
||||
rule rl_fpr_write_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& is_fpr);
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& is_fpr);
|
||||
let req = DM_CPU_Req {write: True,
|
||||
address: fpr_addr,
|
||||
address: fpr_addr,
|
||||
`ifdef RV32
|
||||
data: rg_data0
|
||||
data: rg_data0
|
||||
`endif
|
||||
`ifdef RV64
|
||||
data: {rg_data1, rg_data0}
|
||||
data: {rg_data1, rg_data0}
|
||||
`endif
|
||||
};
|
||||
};
|
||||
f_hart0_fpr_reqs.enq (req);
|
||||
rg_start_reg_access <= False;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_write_start: ", cur_cycle, fshow (req));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_write_start: ", cur_cycle, fshow (req));
|
||||
endrule
|
||||
|
||||
// ----------------
|
||||
|
||||
rule rl_fpr_write_finish ( rg_abstractcs_busy
|
||||
&& rg_command_access_reg_write
|
||||
&& is_fpr);
|
||||
&& rg_command_access_reg_write
|
||||
&& is_fpr);
|
||||
let rsp <- pop (f_hart0_fpr_rsps);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_write_finish: ", cur_cycle, fshow (rsp));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_write_finish: ", cur_cycle, fshow (rsp));
|
||||
|
||||
rg_abstractcs_cmderr <= (rsp.ok ? DM_ABSTRACTCS_CMDERR_NONE : DM_ABSTRACTCS_CMDERR_HALT_RESUME);
|
||||
rg_abstractcs_busy <= False;
|
||||
@@ -423,26 +423,26 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Read FPR
|
||||
|
||||
rule rl_fpr_read_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_fpr);
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_fpr);
|
||||
Bit #(XLEN) data = ?;
|
||||
let req = DM_CPU_Req {write: False, address: fpr_addr, data: data };
|
||||
f_hart0_fpr_reqs.enq (req);
|
||||
rg_start_reg_access <= False;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_read_start: ", cur_cycle, fshow (req));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_read_start: ", cur_cycle, fshow (req));
|
||||
endrule
|
||||
|
||||
// ----------------
|
||||
|
||||
rule rl_fpr_read_finish ( rg_abstractcs_busy
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_fpr);
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& is_fpr);
|
||||
let rsp <- pop (f_hart0_fpr_rsps);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_read_finish: ", cur_cycle, fshow (rsp));
|
||||
$display ("%0d: DM_Abstract_Commands.rl_fpr_read_finish: ", cur_cycle, fshow (rsp));
|
||||
|
||||
`ifdef RV32
|
||||
rg_data0 <= rsp.data;
|
||||
@@ -461,12 +461,12 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
// Read/Write unknown address
|
||||
|
||||
rule rl_unknown_write_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& (! is_csr) && (! is_gpr) && (! is_fpr));
|
||||
&& rg_start_reg_access
|
||||
&& rg_command_access_reg_write
|
||||
&& (! is_csr) && (! is_gpr) && (! is_fpr));
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_unknown_write_start: unknown RISC-V regno [0x%0h] <= 0x%08h",
|
||||
cur_cycle, rg_command_access_reg_regno, rg_data0);
|
||||
$display ("%0d: DM_Abstract_Commands.rl_unknown_write_start: unknown RISC-V regno [0x%0h] <= 0x%08h",
|
||||
cur_cycle, rg_command_access_reg_regno, rg_data0);
|
||||
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_OTHER;
|
||||
rg_start_reg_access <= False;
|
||||
@@ -474,12 +474,12 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
endrule
|
||||
|
||||
rule rl_unknown_read_start ( rg_abstractcs_busy
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& (! is_csr) && (! is_gpr) && (! is_fpr));
|
||||
&& rg_start_reg_access
|
||||
&& (! rg_command_access_reg_write)
|
||||
&& (! is_csr) && (! is_gpr) && (! is_fpr));
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.rl_unknown_read_start: unknown RISC-V regno [0x%0h]",
|
||||
cur_cycle, rg_command_access_reg_regno);
|
||||
$display ("%0d: DM_Abstract_Commands.rl_unknown_read_start: unknown RISC-V regno [0x%0h]",
|
||||
cur_cycle, rg_command_access_reg_regno);
|
||||
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_OTHER;
|
||||
rg_start_reg_access <= False;
|
||||
@@ -509,7 +509,7 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
`endif
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands: reset", cur_cycle);
|
||||
$display ("%0d: DM_Abstract_Commands: reset", cur_cycle);
|
||||
endmethod
|
||||
|
||||
// ----------------
|
||||
@@ -517,64 +517,64 @@ module mkDM_Abstract_Commands (DM_Abstract_Commands_IFC);
|
||||
|
||||
method ActionValue #(DM_Word) av_read (DM_Addr dm_addr);
|
||||
actionvalue
|
||||
let dm_addr_name = fshow_dm_addr (dm_addr);
|
||||
DM_Word dm_word = case (dm_addr)
|
||||
dm_addr_abstractcs: virt_rg_abstractcs;
|
||||
dm_addr_command: virt_rg_command;
|
||||
dm_addr_data0: rg_data0;
|
||||
let dm_addr_name = fshow_dm_addr (dm_addr);
|
||||
DM_Word dm_word = case (dm_addr)
|
||||
dm_addr_abstractcs: virt_rg_abstractcs;
|
||||
dm_addr_command: virt_rg_command;
|
||||
dm_addr_data0: rg_data0;
|
||||
`ifdef RV64
|
||||
dm_addr_data1: rg_data1;
|
||||
dm_addr_data1: rg_data1;
|
||||
`endif
|
||||
// dm_addr_data2..data3
|
||||
// dm_addr_abstractauto
|
||||
// dm_addr_progbuf0..15
|
||||
endcase;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.av_read: [", cur_cycle, dm_addr_name, "] => 0x%08h", dm_word);
|
||||
return dm_word;
|
||||
// dm_addr_data2..data3
|
||||
// dm_addr_abstractauto
|
||||
// dm_addr_progbuf0..15
|
||||
endcase;
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.av_read: [", cur_cycle, dm_addr_name, "] => 0x%08h", dm_word);
|
||||
return dm_word;
|
||||
endactionvalue
|
||||
endmethod
|
||||
|
||||
method Action write (DM_Addr dm_addr, DM_Word dm_word);
|
||||
action
|
||||
let dm_addr_name = fshow_dm_addr (dm_addr);
|
||||
let dm_addr_name = fshow_dm_addr (dm_addr);
|
||||
|
||||
if (dm_addr == dm_addr_abstractcs)
|
||||
fa_rg_abstractcs_write (dm_word);
|
||||
if (dm_addr == dm_addr_abstractcs)
|
||||
fa_rg_abstractcs_write (dm_word);
|
||||
|
||||
else if (rg_abstractcs_cmderr != DM_ABSTRACTCS_CMDERR_NONE) begin
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name, "] <= 0x%08h: ERROR", dm_word);
|
||||
$display (" Ignoring: previous cmderr ", fshow (rg_abstractcs_cmderr));
|
||||
end
|
||||
end
|
||||
else if (rg_abstractcs_cmderr != DM_ABSTRACTCS_CMDERR_NONE) begin
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name, "] <= 0x%08h: ERROR", dm_word);
|
||||
$display (" Ignoring: previous cmderr ", fshow (rg_abstractcs_cmderr));
|
||||
end
|
||||
end
|
||||
|
||||
else if (dm_addr == dm_addr_command)
|
||||
fa_rg_command_write (dm_word);
|
||||
else if (dm_addr == dm_addr_command)
|
||||
fa_rg_command_write (dm_word);
|
||||
|
||||
else if (dm_addr == dm_addr_data0) begin
|
||||
rg_data0 <= dm_word;
|
||||
else if (dm_addr == dm_addr_data0) begin
|
||||
rg_data0 <= dm_word;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name, "] <= 0x%08h", dm_word);
|
||||
end
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name, "] <= 0x%08h", dm_word);
|
||||
end
|
||||
`ifdef RV64
|
||||
else if (dm_addr == dm_addr_data1) begin
|
||||
rg_data1 <= dm_word;
|
||||
else if (dm_addr == dm_addr_data1) begin
|
||||
rg_data1 <= dm_word;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name, "] <= 0x%08h", dm_word);
|
||||
end
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name, "] <= 0x%08h", dm_word);
|
||||
end
|
||||
`endif
|
||||
else begin
|
||||
// dm_addr_data2..12
|
||||
// dm_addr_abstractauto
|
||||
// dm_addr_progbuf0..15
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
else begin
|
||||
// dm_addr_data2..12
|
||||
// dm_addr_abstractauto
|
||||
// dm_addr_progbuf0..15
|
||||
rg_abstractcs_cmderr <= DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED;
|
||||
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name,
|
||||
"] <= 0x%08h: ERROR: not supported", dm_word);
|
||||
end
|
||||
$display ("%0d: DM_Abstract_Commands.write: [", cur_cycle, dm_addr_name,
|
||||
"] <= 0x%08h: ERROR: not supported", dm_word);
|
||||
end
|
||||
endaction
|
||||
endmethod
|
||||
|
||||
|
||||
@@ -83,49 +83,49 @@ DM_Addr dm_addr_sbdata3 = 'h3f;
|
||||
|
||||
function Fmt fshow_dm_addr (DM_Addr dm_addr);
|
||||
return case (dm_addr)
|
||||
// Run Control
|
||||
dm_addr_dmcontrol: $format ("dm_addr_dmcontrol");
|
||||
dm_addr_dmstatus: $format ("dm_addr_dmstatus");
|
||||
dm_addr_hartinfo: $format ("dm_addr_hartinfo");
|
||||
dm_addr_haltsum: $format ("dm_addr_haltsum");
|
||||
dm_addr_hawindowsel: $format ("dm_addr_hawindowsel");
|
||||
dm_addr_hawindow: $format ("dm_addr_hawindow");
|
||||
dm_addr_devtreeaddr0: $format ("dm_addr_devtreeaddr0");
|
||||
dm_addr_authdata: $format ("dm_addr_authdata");
|
||||
dm_addr_haltregion0: $format ("dm_addr_haltregion0");
|
||||
dm_addr_haltregion31: $format ("dm_addr_haltregion31");
|
||||
// Run Control
|
||||
dm_addr_dmcontrol: $format ("dm_addr_dmcontrol");
|
||||
dm_addr_dmstatus: $format ("dm_addr_dmstatus");
|
||||
dm_addr_hartinfo: $format ("dm_addr_hartinfo");
|
||||
dm_addr_haltsum: $format ("dm_addr_haltsum");
|
||||
dm_addr_hawindowsel: $format ("dm_addr_hawindowsel");
|
||||
dm_addr_hawindow: $format ("dm_addr_hawindow");
|
||||
dm_addr_devtreeaddr0: $format ("dm_addr_devtreeaddr0");
|
||||
dm_addr_authdata: $format ("dm_addr_authdata");
|
||||
dm_addr_haltregion0: $format ("dm_addr_haltregion0");
|
||||
dm_addr_haltregion31: $format ("dm_addr_haltregion31");
|
||||
dm_addr_verbosity: $format ("dm_addr_verbosity");
|
||||
|
||||
// Abstract Commands
|
||||
dm_addr_abstractcs: $format ("dm_addr_abstractcs");
|
||||
dm_addr_command: $format ("dm_addr_command");
|
||||
dm_addr_data0: $format ("dm_addr_data0");
|
||||
dm_addr_data1: $format ("dm_addr_data1");
|
||||
dm_addr_data2: $format ("dm_addr_data2");
|
||||
dm_addr_data3: $format ("dm_addr_data3");
|
||||
dm_addr_data4: $format ("dm_addr_data4");
|
||||
dm_addr_data5: $format ("dm_addr_data5");
|
||||
dm_addr_data6: $format ("dm_addr_data6");
|
||||
dm_addr_data7: $format ("dm_addr_data7");
|
||||
dm_addr_data8: $format ("dm_addr_data8");
|
||||
dm_addr_data9: $format ("dm_addr_data9");
|
||||
dm_addr_data10: $format ("dm_addr_data10");
|
||||
dm_addr_data11: $format ("dm_addr_data11");
|
||||
dm_addr_abstractauto: $format ("dm_addr_abstractauto");
|
||||
dm_addr_progbuf0: $format ("dm_addr_progbuf0");
|
||||
// Abstract Commands
|
||||
dm_addr_abstractcs: $format ("dm_addr_abstractcs");
|
||||
dm_addr_command: $format ("dm_addr_command");
|
||||
dm_addr_data0: $format ("dm_addr_data0");
|
||||
dm_addr_data1: $format ("dm_addr_data1");
|
||||
dm_addr_data2: $format ("dm_addr_data2");
|
||||
dm_addr_data3: $format ("dm_addr_data3");
|
||||
dm_addr_data4: $format ("dm_addr_data4");
|
||||
dm_addr_data5: $format ("dm_addr_data5");
|
||||
dm_addr_data6: $format ("dm_addr_data6");
|
||||
dm_addr_data7: $format ("dm_addr_data7");
|
||||
dm_addr_data8: $format ("dm_addr_data8");
|
||||
dm_addr_data9: $format ("dm_addr_data9");
|
||||
dm_addr_data10: $format ("dm_addr_data10");
|
||||
dm_addr_data11: $format ("dm_addr_data11");
|
||||
dm_addr_abstractauto: $format ("dm_addr_abstractauto");
|
||||
dm_addr_progbuf0: $format ("dm_addr_progbuf0");
|
||||
|
||||
// System Bus
|
||||
dm_addr_sbcs: $format ("dm_addr_sbcs");
|
||||
dm_addr_sbaddress0: $format ("dm_addr_sbaddress0");
|
||||
dm_addr_sbaddress1: $format ("dm_addr_sbaddress1");
|
||||
dm_addr_sbaddress2: $format ("dm_addr_sbaddress2");
|
||||
dm_addr_sbdata0: $format ("dm_addr_sbdata0");
|
||||
dm_addr_sbdata1: $format ("dm_addr_sbdata1");
|
||||
dm_addr_sbdata2: $format ("dm_addr_sbdata2");
|
||||
dm_addr_sbdata3: $format ("dm_addr_sbdata3");
|
||||
// System Bus
|
||||
dm_addr_sbcs: $format ("dm_addr_sbcs");
|
||||
dm_addr_sbaddress0: $format ("dm_addr_sbaddress0");
|
||||
dm_addr_sbaddress1: $format ("dm_addr_sbaddress1");
|
||||
dm_addr_sbaddress2: $format ("dm_addr_sbaddress2");
|
||||
dm_addr_sbdata0: $format ("dm_addr_sbdata0");
|
||||
dm_addr_sbdata1: $format ("dm_addr_sbdata1");
|
||||
dm_addr_sbdata2: $format ("dm_addr_sbdata2");
|
||||
dm_addr_sbdata3: $format ("dm_addr_sbdata3");
|
||||
|
||||
default: $format ("<Unknown dm_abstract_command dm_addr 0x%0h>", dm_addr);
|
||||
endcase;
|
||||
default: $format ("<Unknown dm_abstract_command dm_addr 0x%0h>", dm_addr);
|
||||
endcase;
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -135,21 +135,21 @@ endfunction
|
||||
// 'dmcontrol' register
|
||||
|
||||
function DM_Word fn_mk_dmcontrol (Bool haltreq,
|
||||
Bool resumereq,
|
||||
Bool hartreset,
|
||||
Bool hasel,
|
||||
Bit #(10) hartsel,
|
||||
Bool ndmreset,
|
||||
Bool dmactive);
|
||||
Bool resumereq,
|
||||
Bool hartreset,
|
||||
Bool hasel,
|
||||
Bit #(10) hartsel,
|
||||
Bool ndmreset,
|
||||
Bool dmactive);
|
||||
return {pack (haltreq),
|
||||
pack (resumereq),
|
||||
pack (hartreset),
|
||||
2'b0,
|
||||
pack (hasel),
|
||||
hartsel,
|
||||
14'b0,
|
||||
pack (ndmreset),
|
||||
pack (dmactive)};
|
||||
pack (resumereq),
|
||||
pack (hartreset),
|
||||
2'b0,
|
||||
pack (hasel),
|
||||
hartsel,
|
||||
14'b0,
|
||||
pack (ndmreset),
|
||||
pack (dmactive)};
|
||||
endfunction
|
||||
|
||||
function Bool fn_dmcontrol_haltreq (DM_Word dm_word);
|
||||
@@ -241,23 +241,23 @@ endfunction
|
||||
|
||||
function Fmt fshow_dmstatus (DM_Word x);
|
||||
Fmt fmt_version = ( (x[3:0] == 0)
|
||||
? $format ("v.none")
|
||||
: ( (x[3:0] == 1)
|
||||
? $format ("v0.11")
|
||||
: ( (x[3:0] == 2)
|
||||
? $format ("v0.13")
|
||||
: $format ("v??"))));
|
||||
? $format ("v.none")
|
||||
: ( (x[3:0] == 1)
|
||||
? $format ("v0.11")
|
||||
: ( (x[3:0] == 2)
|
||||
? $format ("v0.13")
|
||||
: $format ("v??"))));
|
||||
|
||||
return ( $format ("(all/any) ")
|
||||
+ $format ("resumeack %0d/%0d ", x[17], x[16])
|
||||
+ $format ("nonexistent %0d/%0d ", x[15], x[14])
|
||||
+ $format ("unavail %0d/%0d ", x[13], x[12])
|
||||
+ $format ("running %0d/%0d ", x[11], x[10])
|
||||
+ $format ("halted %0d/%0d ", x[9], x[8])
|
||||
+ $format ("authenticated %0d ", x[7])
|
||||
+ $format ("authbusy %0d ", x[6])
|
||||
+ $format ("devtreevalid %0d ", x[4])
|
||||
+ fmt_version);
|
||||
+ $format ("resumeack %0d/%0d ", x[17], x[16])
|
||||
+ $format ("nonexistent %0d/%0d ", x[15], x[14])
|
||||
+ $format ("unavail %0d/%0d ", x[13], x[12])
|
||||
+ $format ("running %0d/%0d ", x[11], x[10])
|
||||
+ $format ("halted %0d/%0d ", x[9], x[8])
|
||||
+ $format ("authenticated %0d ", x[7])
|
||||
+ $format ("authbusy %0d ", x[6])
|
||||
+ $format ("devtreevalid %0d ", x[4])
|
||||
+ fmt_version);
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -267,13 +267,13 @@ endfunction
|
||||
// 'dm_abstractcs' register
|
||||
|
||||
typedef enum {DM_ABSTRACTCS_CMDERR_NONE, // 0
|
||||
DM_ABSTRACTCS_CMDERR_BUSY, // 1
|
||||
DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED, // 2
|
||||
DM_ABSTRACTCS_CMDERR_EXCEPTION, // 3
|
||||
DM_ABSTRACTCS_CMDERR_HALT_RESUME, // 4
|
||||
DM_ABSTRACTCS_CMDERR_UNDEF5, // 5
|
||||
DM_ABSTRACTCS_CMDERR_UNDEF6, // 6
|
||||
DM_ABSTRACTCS_CMDERR_OTHER // 7
|
||||
DM_ABSTRACTCS_CMDERR_BUSY, // 1
|
||||
DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED, // 2
|
||||
DM_ABSTRACTCS_CMDERR_EXCEPTION, // 3
|
||||
DM_ABSTRACTCS_CMDERR_HALT_RESUME, // 4
|
||||
DM_ABSTRACTCS_CMDERR_UNDEF5, // 5
|
||||
DM_ABSTRACTCS_CMDERR_UNDEF6, // 6
|
||||
DM_ABSTRACTCS_CMDERR_OTHER // 7
|
||||
} DM_abstractcs_cmderr
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
@@ -304,18 +304,18 @@ endfunction
|
||||
// 'command' register
|
||||
|
||||
typedef enum {DM_COMMAND_CMDTYPE_ACCESS_REG,
|
||||
DM_COMMAND_CMDTYPE_QUICK_ACCESS
|
||||
DM_COMMAND_CMDTYPE_QUICK_ACCESS
|
||||
} DM_command_cmdtype
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
typedef enum {DM_COMMAND_ACCESS_REG_SIZE_UNDEF0, // 0
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF1, // 1
|
||||
DM_COMMAND_ACCESS_REG_SIZE_LOWER32, // 2
|
||||
DM_COMMAND_ACCESS_REG_SIZE_LOWER64, // 3
|
||||
DM_COMMAND_ACCESS_REG_SIZE_LOWER128, // 4
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF5, // 5
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF6, // 6
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF7 // 7
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF1, // 1
|
||||
DM_COMMAND_ACCESS_REG_SIZE_LOWER32, // 2
|
||||
DM_COMMAND_ACCESS_REG_SIZE_LOWER64, // 3
|
||||
DM_COMMAND_ACCESS_REG_SIZE_LOWER128, // 4
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF5, // 5
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF6, // 6
|
||||
DM_COMMAND_ACCESS_REG_SIZE_UNDEF7 // 7
|
||||
} DM_command_access_reg_size
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
@@ -327,20 +327,20 @@ Integer dm_command_access_reg_regno_fpr_0 = 'h1020;
|
||||
Integer dm_command_access_reg_regno_fpr_1F = 'h103F;
|
||||
|
||||
function DM_Word fn_mk_command_access_reg (DM_command_access_reg_size size,
|
||||
Bool postexec,
|
||||
Bool transfer,
|
||||
Bool write,
|
||||
Bit #(16) regno);
|
||||
Bool postexec,
|
||||
Bool transfer,
|
||||
Bool write,
|
||||
Bit #(16) regno);
|
||||
Bit #(8) b8_cmdtype = zeroExtend (pack (DM_COMMAND_CMDTYPE_ACCESS_REG));
|
||||
Bit #(3) b3_size = pack (size);
|
||||
return {b8_cmdtype,
|
||||
1'b0,
|
||||
b3_size,
|
||||
1'b0,
|
||||
pack (postexec),
|
||||
pack (transfer),
|
||||
pack (write),
|
||||
regno};
|
||||
1'b0,
|
||||
b3_size,
|
||||
1'b0,
|
||||
pack (postexec),
|
||||
pack (transfer),
|
||||
pack (write),
|
||||
regno};
|
||||
endfunction
|
||||
|
||||
function DM_command_cmdtype fn_command_cmdtype (DM_Word dm_word);
|
||||
@@ -374,10 +374,10 @@ endfunction
|
||||
// 'dm_sbcs' register
|
||||
|
||||
typedef enum {DM_SBACCESS_8_BIT,
|
||||
DM_SBACCESS_16_BIT,
|
||||
DM_SBACCESS_32_BIT,
|
||||
DM_SBACCESS_64_BIT,
|
||||
DM_SBACCESS_128_BIT
|
||||
DM_SBACCESS_16_BIT,
|
||||
DM_SBACCESS_32_BIT,
|
||||
DM_SBACCESS_64_BIT,
|
||||
DM_SBACCESS_128_BIT
|
||||
} DM_sbaccess
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
@@ -392,47 +392,47 @@ function Integer fn_sbaccess_to_addr_incr (DM_sbaccess sbaccess);
|
||||
endfunction
|
||||
|
||||
typedef enum {DM_SBERROR_NONE, // 0
|
||||
DM_SBERROR_TIMEOUT, // 1
|
||||
DM_SBERROR_BADADDR, // 2
|
||||
DM_SBERROR_OTHER, // 3
|
||||
DM_SBERROR_BUSY_STALE, // 4
|
||||
DM_SBERROR_UNDEF5, // 5
|
||||
DM_SBERROR_UNDEF6, // 6
|
||||
DM_SBERROR_UNDEF7_W1C // 7, used in writes, to clear sberror
|
||||
DM_SBERROR_TIMEOUT, // 1
|
||||
DM_SBERROR_BADADDR, // 2
|
||||
DM_SBERROR_OTHER, // 3
|
||||
DM_SBERROR_BUSY_STALE, // 4
|
||||
DM_SBERROR_UNDEF5, // 5
|
||||
DM_SBERROR_UNDEF6, // 6
|
||||
DM_SBERROR_UNDEF7_W1C // 7, used in writes, to clear sberror
|
||||
} DM_sberror
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
// Constructor
|
||||
|
||||
function DM_Word fn_mk_sbcs_val (Bit #(3) sbversion,
|
||||
Bool sbbusyerror,
|
||||
Bool sbbusy,
|
||||
Bool sbreadonaddr,
|
||||
DM_sbaccess sbaccess,
|
||||
Bool sbautoincrement,
|
||||
Bool sbreadondata,
|
||||
DM_sberror sberror,
|
||||
Bit #(7) sbasize,
|
||||
Bit #(1) sbaccess128,
|
||||
Bit #(1) sbaccess64,
|
||||
Bit #(1) sbaccess32,
|
||||
Bit #(1) sbaccess16,
|
||||
Bit #(1) sbaccess8);
|
||||
Bool sbbusyerror,
|
||||
Bool sbbusy,
|
||||
Bool sbreadonaddr,
|
||||
DM_sbaccess sbaccess,
|
||||
Bool sbautoincrement,
|
||||
Bool sbreadondata,
|
||||
DM_sberror sberror,
|
||||
Bit #(7) sbasize,
|
||||
Bit #(1) sbaccess128,
|
||||
Bit #(1) sbaccess64,
|
||||
Bit #(1) sbaccess32,
|
||||
Bit #(1) sbaccess16,
|
||||
Bit #(1) sbaccess8);
|
||||
return {sbversion,
|
||||
6'b0,
|
||||
pack (sbbusyerror),
|
||||
pack (sbbusy),
|
||||
pack (sbreadonaddr),
|
||||
pack (sbaccess),
|
||||
pack (sbautoincrement),
|
||||
pack (sbreadondata),
|
||||
pack (sberror),
|
||||
sbasize,
|
||||
sbaccess128,
|
||||
sbaccess64,
|
||||
sbaccess32,
|
||||
sbaccess16,
|
||||
sbaccess8};
|
||||
6'b0,
|
||||
pack (sbbusyerror),
|
||||
pack (sbbusy),
|
||||
pack (sbreadonaddr),
|
||||
pack (sbaccess),
|
||||
pack (sbautoincrement),
|
||||
pack (sbreadondata),
|
||||
pack (sberror),
|
||||
sbasize,
|
||||
sbaccess128,
|
||||
sbaccess64,
|
||||
sbaccess32,
|
||||
sbaccess16,
|
||||
sbaccess8};
|
||||
endfunction
|
||||
|
||||
// Selectors
|
||||
@@ -456,35 +456,35 @@ function Bool fn_sbcs_sbaccess8 (DM_Word dm_word); return unpack (
|
||||
|
||||
function Fmt fshow_sbcs (DM_Word dm_word);
|
||||
return ( $format ("SBCS{")
|
||||
+ $format ("sbversion %0d", fn_sbcs_sbversion (dm_word))
|
||||
+ $format (" sbbusyerror %0d", fn_sbcs_sbbusyerror (dm_word))
|
||||
+ $format (" sbbusy %0d", fn_sbcs_sbbusy (dm_word))
|
||||
+ $format (" sbreadonaddr ") + fshow (fn_sbcs_sbreadonaddr (dm_word))
|
||||
+ $format (" sbaccess ") + fshow (fn_sbcs_sbaccess (dm_word))
|
||||
+ $format (" sbautoincrement ") + fshow (fn_sbcs_sbautoincrement (dm_word))
|
||||
+ $format (" sbreadondata ") + fshow (fn_sbcs_sbreadondata (dm_word))
|
||||
+ $format (" sberror ") + fshow (fn_sbcs_sberror (dm_word))
|
||||
+ $format (" sbasize %0d", fn_sbcs_sbasize (dm_word))
|
||||
+ $format (" sbaccess")
|
||||
+ ((fn_sbcs_sbaccess128 (dm_word)) ? $format ("_128") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess64 (dm_word)) ? $format ("_64") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess32 (dm_word)) ? $format ("_32") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess16 (dm_word)) ? $format ("_16") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess8 (dm_word)) ? $format ("_8") : $format ("x"))
|
||||
+ $format ("}"));
|
||||
+ $format ("sbversion %0d", fn_sbcs_sbversion (dm_word))
|
||||
+ $format (" sbbusyerror %0d", fn_sbcs_sbbusyerror (dm_word))
|
||||
+ $format (" sbbusy %0d", fn_sbcs_sbbusy (dm_word))
|
||||
+ $format (" sbreadonaddr ") + fshow (fn_sbcs_sbreadonaddr (dm_word))
|
||||
+ $format (" sbaccess ") + fshow (fn_sbcs_sbaccess (dm_word))
|
||||
+ $format (" sbautoincrement ") + fshow (fn_sbcs_sbautoincrement (dm_word))
|
||||
+ $format (" sbreadondata ") + fshow (fn_sbcs_sbreadondata (dm_word))
|
||||
+ $format (" sberror ") + fshow (fn_sbcs_sberror (dm_word))
|
||||
+ $format (" sbasize %0d", fn_sbcs_sbasize (dm_word))
|
||||
+ $format (" sbaccess")
|
||||
+ ((fn_sbcs_sbaccess128 (dm_word)) ? $format ("_128") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess64 (dm_word)) ? $format ("_64") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess32 (dm_word)) ? $format ("_32") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess16 (dm_word)) ? $format ("_16") : $format ("x"))
|
||||
+ ((fn_sbcs_sbaccess8 (dm_word)) ? $format ("_8") : $format ("x"))
|
||||
+ $format ("}"));
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
// DCSR 'cause' field values
|
||||
|
||||
typedef enum {DCSR_CAUSE_RESERVED0,
|
||||
DCSR_CAUSE_EBREAK,
|
||||
DCSR_CAUSE_TRIGGER,
|
||||
DCSR_CAUSE_HALTREQ,
|
||||
DCSR_CAUSE_STEP,
|
||||
DCSR_CAUSE_RESERVED5,
|
||||
DCSR_CAUSE_RESERVED6,
|
||||
DCSR_CAUSE_RESERVED7
|
||||
DCSR_CAUSE_EBREAK,
|
||||
DCSR_CAUSE_TRIGGER,
|
||||
DCSR_CAUSE_HALTREQ,
|
||||
DCSR_CAUSE_STEP,
|
||||
DCSR_CAUSE_RESERVED5,
|
||||
DCSR_CAUSE_RESERVED6,
|
||||
DCSR_CAUSE_RESERVED7
|
||||
} DCSR_Cause
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
@@ -500,12 +500,12 @@ endinterface
|
||||
// A dummy interface to tie off DMI if it is not used.
|
||||
|
||||
DMI dummy_DMI_ifc = interface DMI;
|
||||
method Action read_addr (DM_Addr dm_addr) = noAction;
|
||||
method ActionValue #(DM_Word) read_data = actionvalue
|
||||
return 0;
|
||||
endactionvalue;
|
||||
method Action write (DM_Addr dm_addr, DM_Word dm_word) = noAction;
|
||||
endinterface;
|
||||
method Action read_addr (DM_Addr dm_addr) = noAction;
|
||||
method ActionValue #(DM_Word) read_data = actionvalue
|
||||
return 0;
|
||||
endactionvalue;
|
||||
method Action write (DM_Addr dm_addr, DM_Word dm_word) = noAction;
|
||||
endinterface;
|
||||
|
||||
// ================================================================
|
||||
|
||||
|
||||
@@ -115,25 +115,25 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
Bool dmstatus_anyhalted = dmstatus_allhalted;
|
||||
|
||||
DM_Word virt_rg_dmstatus = {9'b0,
|
||||
pack (dmstatus_impebreak),
|
||||
2'b0,
|
||||
pack (dmstatus_allhavereset),
|
||||
pack (dmstatus_anyhavereset),
|
||||
pack (dmstatus_allresumeack),
|
||||
pack (dmstatus_anyresumeack),
|
||||
pack (dmstatus_allnonexistent),
|
||||
pack (dmstatus_anynonexistent),
|
||||
pack (dmstatus_allunavail),
|
||||
pack (dmstatus_anyunavail),
|
||||
pack (dmstatus_allrunning),
|
||||
pack (dmstatus_anyrunning),
|
||||
pack (dmstatus_allhalted),
|
||||
pack (dmstatus_anyhalted),
|
||||
pack (True), // authenticated
|
||||
pack (False), // authbusy
|
||||
1'b0,
|
||||
pack (False), // devtreevalid
|
||||
4'h2}; // version
|
||||
pack (dmstatus_impebreak),
|
||||
2'b0,
|
||||
pack (dmstatus_allhavereset),
|
||||
pack (dmstatus_anyhavereset),
|
||||
pack (dmstatus_allresumeack),
|
||||
pack (dmstatus_anyresumeack),
|
||||
pack (dmstatus_allnonexistent),
|
||||
pack (dmstatus_anynonexistent),
|
||||
pack (dmstatus_allunavail),
|
||||
pack (dmstatus_anyunavail),
|
||||
pack (dmstatus_allrunning),
|
||||
pack (dmstatus_anyrunning),
|
||||
pack (dmstatus_allhalted),
|
||||
pack (dmstatus_anyhalted),
|
||||
pack (True), // authenticated
|
||||
pack (False), // authbusy
|
||||
1'b0,
|
||||
pack (False), // devtreevalid
|
||||
4'h2}; // version
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// rg_dmcontrol
|
||||
@@ -145,131 +145,131 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
Reg #(Bool) rg_dmcontrol_dmactive <- mkReg (False);
|
||||
|
||||
DM_Word virt_rg_dmcontrol = {2'b0, // haltreq, resumereq (w-o)
|
||||
pack (rg_dmcontrol_hartreset),
|
||||
2'b0,
|
||||
pack (False), // hasel
|
||||
10'b0, // hartsel
|
||||
14'b0,
|
||||
pack (rg_dmcontrol_ndmreset),
|
||||
pack (rg_dmcontrol_dmactive)};
|
||||
pack (rg_dmcontrol_hartreset),
|
||||
2'b0,
|
||||
pack (False), // hasel
|
||||
10'b0, // hartsel
|
||||
14'b0,
|
||||
pack (rg_dmcontrol_ndmreset),
|
||||
pack (rg_dmcontrol_dmactive)};
|
||||
|
||||
function Action fa_rg_dmcontrol_write (DM_Word dm_word);
|
||||
action
|
||||
let haltreq = fn_dmcontrol_haltreq (dm_word);
|
||||
let resumereq = fn_dmcontrol_resumereq (dm_word);
|
||||
let hartreset = fn_dmcontrol_hartreset (dm_word);
|
||||
let hasel = fn_dmcontrol_hasel (dm_word);
|
||||
let hartsel = fn_dmcontrol_hartsel (dm_word);
|
||||
let ndmreset = fn_dmcontrol_ndmreset (dm_word);
|
||||
let dmactive = fn_dmcontrol_dmactive (dm_word);
|
||||
let haltreq = fn_dmcontrol_haltreq (dm_word);
|
||||
let resumereq = fn_dmcontrol_resumereq (dm_word);
|
||||
let hartreset = fn_dmcontrol_hartreset (dm_word);
|
||||
let hasel = fn_dmcontrol_hasel (dm_word);
|
||||
let hartsel = fn_dmcontrol_hartsel (dm_word);
|
||||
let ndmreset = fn_dmcontrol_ndmreset (dm_word);
|
||||
let dmactive = fn_dmcontrol_dmactive (dm_word);
|
||||
|
||||
rg_dmcontrol_haltreq <= haltreq;
|
||||
rg_dmcontrol_hartreset <= hartreset;
|
||||
rg_dmcontrol_ndmreset <= ndmreset;
|
||||
rg_dmcontrol_dmactive <= dmactive;
|
||||
rg_dmcontrol_haltreq <= haltreq;
|
||||
rg_dmcontrol_hartreset <= hartreset;
|
||||
rg_dmcontrol_ndmreset <= ndmreset;
|
||||
rg_dmcontrol_dmactive <= dmactive;
|
||||
|
||||
// Debug Module reset
|
||||
if (! dmactive) begin
|
||||
// Reset the DM module itself
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h (dmactive=0): resetting Debug Module",
|
||||
cur_cycle, dm_word);
|
||||
// Debug Module reset
|
||||
if (! dmactive) begin
|
||||
// Reset the DM module itself
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h (dmactive=0): resetting Debug Module",
|
||||
cur_cycle, dm_word);
|
||||
|
||||
// Error-checking
|
||||
if (ndmreset) begin
|
||||
$display (" WARNING: DM_Run_Control: dmcontrol_write 0x%08h:", dm_word);
|
||||
$display (" [1] (ndmreset) and [0] (dmactive) both asserted");
|
||||
$display (" dmactive has priority; ignoring ndmreset");
|
||||
end
|
||||
if (hartreset) begin
|
||||
$display (" WARNING: DM_Run_Control: dmcontrol_write 0x%08h:", dm_word);
|
||||
$display (" [29] (hartreset) and [0] (dmactive) both asserted");
|
||||
$display (" dmactive has priority; ignoring hartreset");
|
||||
end
|
||||
// Error-checking
|
||||
if (ndmreset) begin
|
||||
$display (" WARNING: DM_Run_Control: dmcontrol_write 0x%08h:", dm_word);
|
||||
$display (" [1] (ndmreset) and [0] (dmactive) both asserted");
|
||||
$display (" dmactive has priority; ignoring ndmreset");
|
||||
end
|
||||
if (hartreset) begin
|
||||
$display (" WARNING: DM_Run_Control: dmcontrol_write 0x%08h:", dm_word);
|
||||
$display (" [29] (hartreset) and [0] (dmactive) both asserted");
|
||||
$display (" dmactive has priority; ignoring hartreset");
|
||||
end
|
||||
|
||||
// No action here; other rules will fire (see method dmactive, Debug_Module.rl_reset)
|
||||
noAction;
|
||||
end
|
||||
// No action here; other rules will fire (see method dmactive, Debug_Module.rl_reset)
|
||||
noAction;
|
||||
end
|
||||
|
||||
// Ignore if NDM reset is in progress
|
||||
else if (rg_dmstatus_allunavail) begin
|
||||
$display ("%0d: %m.dmcontrol_write 0x%0h: ndm reset in progress; ignoring this write",
|
||||
cur_cycle, dm_word);
|
||||
end
|
||||
// Ignore if NDM reset is in progress
|
||||
else if (rg_dmstatus_allunavail) begin
|
||||
$display ("%0d: %m.dmcontrol_write 0x%0h: ndm reset in progress; ignoring this write",
|
||||
cur_cycle, dm_word);
|
||||
end
|
||||
|
||||
// Non-Debug-Module reset (platform reset) posedge: ignore
|
||||
else if ((! rg_dmcontrol_ndmreset) && ndmreset) begin
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: ndmreset: 0->1: ignoring",
|
||||
cur_cycle, dm_word);
|
||||
end
|
||||
// Non-Debug-Module reset (platform reset) posedge: ignore
|
||||
else if ((! rg_dmcontrol_ndmreset) && ndmreset) begin
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: ndmreset: 0->1: ignoring",
|
||||
cur_cycle, dm_word);
|
||||
end
|
||||
|
||||
// Non-Debug-Module reset (platform reset) negedge: do it
|
||||
else if (rg_dmcontrol_ndmreset && (! ndmreset)) begin
|
||||
Bool running = (! haltreq);
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: ndmreset: 1->0: resetting platform",
|
||||
cur_cycle, dm_word);
|
||||
$display (" Requested 'running' state = ", fshow (running));
|
||||
end
|
||||
// Non-Debug-Module reset (platform reset) negedge: do it
|
||||
else if (rg_dmcontrol_ndmreset && (! ndmreset)) begin
|
||||
Bool running = (! haltreq);
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: ndmreset: 1->0: resetting platform",
|
||||
cur_cycle, dm_word);
|
||||
$display (" Requested 'running' state = ", fshow (running));
|
||||
end
|
||||
|
||||
f_ndm_reset_reqs.enq (running);
|
||||
rg_dmstatus_allunavail <= True;
|
||||
f_ndm_reset_reqs.enq (running);
|
||||
rg_dmstatus_allunavail <= True;
|
||||
|
||||
// Error-checking
|
||||
if (hartreset) begin
|
||||
$display (" WARNING: %m.dmcontrol_write 0x%08h:", dm_word);
|
||||
$display (" Both ndmreset [1] and hartreset [29] are asserted");
|
||||
$display (" ndmreset has priority; ignoring hartreset");
|
||||
end
|
||||
// Error-checking
|
||||
if (hartreset) begin
|
||||
$display (" WARNING: %m.dmcontrol_write 0x%08h:", dm_word);
|
||||
$display (" Both ndmreset [1] and hartreset [29] are asserted");
|
||||
$display (" ndmreset has priority; ignoring hartreset");
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
// Hart reset
|
||||
else if (hartreset) begin
|
||||
Bool running = (! haltreq);
|
||||
f_hart0_reset_reqs.enq (running);
|
||||
rg_hart0_hasreset <= True;
|
||||
// Hart reset
|
||||
else if (hartreset) begin
|
||||
Bool running = (! haltreq);
|
||||
f_hart0_reset_reqs.enq (running);
|
||||
rg_hart0_hasreset <= True;
|
||||
|
||||
// Deassert platform reset
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: hartreset=1: resetting hart",
|
||||
cur_cycle, dm_word);
|
||||
$display (" Requested 'running' state = ", fshow (running));
|
||||
end
|
||||
end
|
||||
// Deassert platform reset
|
||||
if (verbosity != 0) begin
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: hartreset=1: resetting hart",
|
||||
cur_cycle, dm_word);
|
||||
$display (" Requested 'running' state = ", fshow (running));
|
||||
end
|
||||
end
|
||||
|
||||
// run/halt commands
|
||||
else begin
|
||||
// Deassert hart reset
|
||||
if ((verbosity != 0) && rg_dmcontrol_hartreset)
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: clearing hartreset",
|
||||
cur_cycle, dm_word);
|
||||
// run/halt commands
|
||||
else begin
|
||||
// Deassert hart reset
|
||||
if ((verbosity != 0) && rg_dmcontrol_hartreset)
|
||||
$display ("%0d: %m.dmcontrol_write 0x%08h: clearing hartreset",
|
||||
cur_cycle, dm_word);
|
||||
|
||||
if (hasel)
|
||||
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: hasel is not supported",
|
||||
cur_cycle, dm_word);
|
||||
if (hasel)
|
||||
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: hasel is not supported",
|
||||
cur_cycle, dm_word);
|
||||
|
||||
if (hartsel != 0)
|
||||
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: hartsel 0x%0h not supported",
|
||||
cur_cycle, dm_word, hartsel);
|
||||
if (hartsel != 0)
|
||||
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: hartsel 0x%0h not supported",
|
||||
cur_cycle, dm_word, hartsel);
|
||||
|
||||
if (haltreq && resumereq) begin
|
||||
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: haltreq=1 and resumereq=1",
|
||||
cur_cycle, dm_word);
|
||||
$display (" This behavior is 'undefined' in the spec; ignoring");
|
||||
end
|
||||
// Resume hart(s) if not running
|
||||
else if (resumereq && (! rg_hart0_running)) begin
|
||||
f_hart0_run_halt_reqs.enq (True);
|
||||
rg_dmstatus_allresumeack <= False;
|
||||
$display ("%0d: %m.dmcontrol_write: hart0 resume request", cur_cycle);
|
||||
end
|
||||
// Halt hart(s)
|
||||
else if (haltreq && rg_hart0_running) begin
|
||||
f_hart0_run_halt_reqs.enq (False);
|
||||
$display ("%0d: %m.dmcontrol_write: hart0 halt request", cur_cycle);
|
||||
end
|
||||
end
|
||||
if (haltreq && resumereq) begin
|
||||
$display ("%0d:ERROR: %m.dmcontrol_write 0x%08h: haltreq=1 and resumereq=1",
|
||||
cur_cycle, dm_word);
|
||||
$display (" This behavior is 'undefined' in the spec; ignoring");
|
||||
end
|
||||
// Resume hart(s) if not running
|
||||
else if (resumereq && (! rg_hart0_running)) begin
|
||||
f_hart0_run_halt_reqs.enq (True);
|
||||
rg_dmstatus_allresumeack <= False;
|
||||
$display ("%0d: %m.dmcontrol_write: hart0 resume request", cur_cycle);
|
||||
end
|
||||
// Halt hart(s)
|
||||
else if (haltreq && rg_hart0_running) begin
|
||||
f_hart0_run_halt_reqs.enq (False);
|
||||
$display ("%0d: %m.dmcontrol_write: hart0 halt request", cur_cycle);
|
||||
end
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -298,7 +298,7 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
rg_hart0_running <= running;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.rl_hart0_reset_rsp: hart running = ", cur_cycle, fshow (running));
|
||||
$display ("%0d: %m.rl_hart0_reset_rsp: hart running = ", cur_cycle, fshow (running));
|
||||
endrule
|
||||
|
||||
// Response from system for NDM reset
|
||||
@@ -308,7 +308,7 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
rg_dmstatus_allunavail <= False;
|
||||
|
||||
// if (verbosity != 0) TODO: UNCOMMENT AFTER DEBUGGING
|
||||
$display ("%0d: %m.rl_ndm_reset_rsp: hart running = ", cur_cycle, fshow (running));
|
||||
$display ("%0d: %m.rl_ndm_reset_rsp: hart running = ", cur_cycle, fshow (running));
|
||||
endrule
|
||||
|
||||
// Response from system for run/halt request
|
||||
@@ -316,10 +316,10 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
let running <- pop (f_hart0_run_halt_rsps);
|
||||
rg_hart0_running <= running;
|
||||
if (running)
|
||||
rg_dmstatus_allresumeack <= True;
|
||||
rg_dmstatus_allresumeack <= True;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.rl_hart0_run_rsp: 'running' = ", cur_cycle, fshow (running));
|
||||
$display ("%0d: %m.rl_hart0_run_rsp: 'running' = ", cur_cycle, fshow (running));
|
||||
endrule
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
@@ -352,7 +352,7 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
rg_verbosity <= 0;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.reset", cur_cycle);
|
||||
$display ("%0d: %m.reset", cur_cycle);
|
||||
endmethod
|
||||
|
||||
// ----------------
|
||||
@@ -360,34 +360,34 @@ module mkDM_Run_Control (DM_Run_Control_IFC);
|
||||
|
||||
method ActionValue #(DM_Word) av_read (DM_Addr dm_addr);
|
||||
actionvalue
|
||||
DM_Word dm_word = case (dm_addr)
|
||||
dm_addr_dmcontrol: virt_rg_dmcontrol;
|
||||
dm_addr_dmstatus: virt_rg_dmstatus;
|
||||
dm_addr_haltsum: haltsum;
|
||||
dm_addr_haltregion0: haltregion0;
|
||||
dm_addr_verbosity: extend (rg_verbosity);
|
||||
endcase;
|
||||
DM_Word dm_word = case (dm_addr)
|
||||
dm_addr_dmcontrol: virt_rg_dmcontrol;
|
||||
dm_addr_dmstatus: virt_rg_dmstatus;
|
||||
dm_addr_haltsum: haltsum;
|
||||
dm_addr_haltregion0: haltregion0;
|
||||
dm_addr_verbosity: extend (rg_verbosity);
|
||||
endcase;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.av_read: [", cur_cycle, fshow_dm_addr (dm_addr), "] => 0x%08h", dm_word);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.av_read: [", cur_cycle, fshow_dm_addr (dm_addr), "] => 0x%08h", dm_word);
|
||||
|
||||
return dm_word;
|
||||
return dm_word;
|
||||
endactionvalue
|
||||
endmethod
|
||||
|
||||
method Action write (DM_Addr dm_addr, DM_Word dm_word);
|
||||
action
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.write: [", cur_cycle, fshow_dm_addr (dm_addr), "] <= 0x%08h", dm_word);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.write: [", cur_cycle, fshow_dm_addr (dm_addr), "] <= 0x%08h", dm_word);
|
||||
|
||||
case (dm_addr)
|
||||
dm_addr_dmcontrol: fa_rg_dmcontrol_write (dm_word);
|
||||
dm_addr_verbosity: begin
|
||||
rg_verbosity <= truncate (dm_word);
|
||||
f_hart0_other_reqs.enq (truncate (dm_word));
|
||||
end
|
||||
default: noAction;
|
||||
endcase
|
||||
case (dm_addr)
|
||||
dm_addr_dmcontrol: fa_rg_dmcontrol_write (dm_word);
|
||||
dm_addr_verbosity: begin
|
||||
rg_verbosity <= truncate (dm_word);
|
||||
f_hart0_other_reqs.enq (truncate (dm_word));
|
||||
end
|
||||
default: noAction;
|
||||
endcase
|
||||
endaction
|
||||
endmethod
|
||||
|
||||
|
||||
@@ -49,11 +49,11 @@ endinterface
|
||||
|
||||
function AXI4_Size fn_DM_sbaccess_to_AXI4_Size (DM_sbaccess sbaccess);
|
||||
AXI4_Size axi4_size = case (sbaccess)
|
||||
DM_SBACCESS_8_BIT: axsize_1;
|
||||
DM_SBACCESS_16_BIT: axsize_2;
|
||||
DM_SBACCESS_32_BIT: axsize_4;
|
||||
DM_SBACCESS_64_BIT: axsize_8;
|
||||
endcase;
|
||||
DM_SBACCESS_8_BIT: axsize_1;
|
||||
DM_SBACCESS_16_BIT: axsize_2;
|
||||
DM_SBACCESS_32_BIT: axsize_4;
|
||||
DM_SBACCESS_64_BIT: axsize_8;
|
||||
endcase;
|
||||
return axi4_size;
|
||||
endfunction
|
||||
|
||||
@@ -68,8 +68,8 @@ endfunction
|
||||
// - word with correct byte(s) shifted into LSBs and zero extended
|
||||
|
||||
function Bit #(64) fn_extract_and_extend_bytes (DM_sbaccess sbaccess,
|
||||
Bit #(64) read_addr,
|
||||
Bit #(64) word64);
|
||||
Bit #(64) read_addr,
|
||||
Bit #(64) word64);
|
||||
Bit #(3) addr_lsbs = read_addr [2:0];
|
||||
if (valueOf (Wd_Data) == 32)
|
||||
addr_lsbs = (addr_lsbs & 'h3);
|
||||
@@ -77,31 +77,31 @@ function Bit #(64) fn_extract_and_extend_bytes (DM_sbaccess sbaccess,
|
||||
Bit #(64) result = 0;
|
||||
case (sbaccess)
|
||||
DM_SBACCESS_8_BIT: case (addr_lsbs)
|
||||
'h0: result = zeroExtend (word64 [ 7: 0]);
|
||||
'h1: result = zeroExtend (word64 [15: 8]);
|
||||
'h2: result = zeroExtend (word64 [23:16]);
|
||||
'h3: result = zeroExtend (word64 [31:24]);
|
||||
'h4: result = zeroExtend (word64 [39:32]);
|
||||
'h5: result = zeroExtend (word64 [47:40]);
|
||||
'h6: result = zeroExtend (word64 [55:48]);
|
||||
'h7: result = zeroExtend (word64 [63:56]);
|
||||
endcase
|
||||
'h0: result = zeroExtend (word64 [ 7: 0]);
|
||||
'h1: result = zeroExtend (word64 [15: 8]);
|
||||
'h2: result = zeroExtend (word64 [23:16]);
|
||||
'h3: result = zeroExtend (word64 [31:24]);
|
||||
'h4: result = zeroExtend (word64 [39:32]);
|
||||
'h5: result = zeroExtend (word64 [47:40]);
|
||||
'h6: result = zeroExtend (word64 [55:48]);
|
||||
'h7: result = zeroExtend (word64 [63:56]);
|
||||
endcase
|
||||
|
||||
DM_SBACCESS_16_BIT: case (addr_lsbs)
|
||||
'h0: result = zeroExtend (word64 [15: 0]);
|
||||
'h2: result = zeroExtend (word64 [31:16]);
|
||||
'h4: result = zeroExtend (word64 [47:32]);
|
||||
'h6: result = zeroExtend (word64 [63:48]);
|
||||
endcase
|
||||
'h0: result = zeroExtend (word64 [15: 0]);
|
||||
'h2: result = zeroExtend (word64 [31:16]);
|
||||
'h4: result = zeroExtend (word64 [47:32]);
|
||||
'h6: result = zeroExtend (word64 [63:48]);
|
||||
endcase
|
||||
|
||||
DM_SBACCESS_32_BIT: case (addr_lsbs)
|
||||
'h0: result = zeroExtend (word64 [31: 0]);
|
||||
'h4: result = zeroExtend (word64 [63:32]);
|
||||
endcase
|
||||
'h0: result = zeroExtend (word64 [31: 0]);
|
||||
'h4: result = zeroExtend (word64 [63:32]);
|
||||
endcase
|
||||
|
||||
DM_SBACCESS_64_BIT: case (addr_lsbs)
|
||||
'h0: result = word64;
|
||||
endcase
|
||||
'h0: result = word64;
|
||||
endcase
|
||||
endcase
|
||||
return result;
|
||||
endfunction
|
||||
@@ -110,12 +110,12 @@ endfunction
|
||||
// Compute address, data and strobe (byte-enables) for writes to fabric
|
||||
|
||||
function Tuple4 #(Fabric_Addr, // addr is 32b- or 64b-aligned
|
||||
Fabric_Data, // data is lane-aligned
|
||||
Fabric_Strb, // strobe
|
||||
AXI4_Size) // 8 for 8-byte writes, else 4
|
||||
Fabric_Data, // data is lane-aligned
|
||||
Fabric_Strb, // strobe
|
||||
AXI4_Size) // 8 for 8-byte writes, else 4
|
||||
fn_to_fabric_write_fields (DM_sbaccess sbaccess, // size of access
|
||||
Bit #(64) addr,
|
||||
Bit #(64) word64); // data is in lsbs
|
||||
Bit #(64) addr,
|
||||
Bit #(64) word64); // data is in lsbs
|
||||
|
||||
// First compute addr, data and strobe for a 64b-wide fabric
|
||||
Bit #(8) strobe64 = 0;
|
||||
@@ -125,24 +125,24 @@ function Tuple4 #(Fabric_Addr, // addr is 32b- or 64b-aligned
|
||||
|
||||
case (sbaccess)
|
||||
DM_SBACCESS_8_BIT: begin
|
||||
word64 = (word64 << shift_bits);
|
||||
strobe64 = ('b_1 << shift_bytes);
|
||||
axsize = axsize_1;
|
||||
end
|
||||
word64 = (word64 << shift_bits);
|
||||
strobe64 = ('b_1 << shift_bytes);
|
||||
axsize = axsize_1;
|
||||
end
|
||||
DM_SBACCESS_16_BIT: begin
|
||||
word64 = (word64 << shift_bits);
|
||||
strobe64 = ('b_11 << shift_bytes);
|
||||
axsize = axsize_2;
|
||||
end
|
||||
word64 = (word64 << shift_bits);
|
||||
strobe64 = ('b_11 << shift_bytes);
|
||||
axsize = axsize_2;
|
||||
end
|
||||
DM_SBACCESS_32_BIT: begin
|
||||
word64 = (word64 << shift_bits);
|
||||
strobe64 = ('b_1111 << shift_bytes);
|
||||
axsize = axsize_4;
|
||||
end
|
||||
word64 = (word64 << shift_bits);
|
||||
strobe64 = ('b_1111 << shift_bytes);
|
||||
axsize = axsize_4;
|
||||
end
|
||||
DM_SBACCESS_64_BIT: begin
|
||||
strobe64 = 'b_1111_1111;
|
||||
axsize = axsize_8;
|
||||
end
|
||||
strobe64 = 'b_1111_1111;
|
||||
axsize = axsize_8;
|
||||
end
|
||||
endcase
|
||||
|
||||
// Adjust for 32b fabrics
|
||||
@@ -163,8 +163,8 @@ endfunction: fn_to_fabric_write_fields
|
||||
// System Bus access states
|
||||
|
||||
typedef enum {SB_NOTBUSY,
|
||||
SB_READ_FINISH,
|
||||
SB_WRITE_FINISH
|
||||
SB_READ_FINISH,
|
||||
SB_WRITE_FINISH
|
||||
} SB_State
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
@@ -218,25 +218,25 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
UInt #(3) sbversion = 1;
|
||||
|
||||
DM_Word virt_rg_sbcs = {pack (sbversion),
|
||||
6'b0,
|
||||
pack (rg_sbcs_sbbusyerror),
|
||||
pack (sbbusy),
|
||||
pack (rg_sbcs_sbreadonaddr),
|
||||
pack (rg_sbcs_sbaccess),
|
||||
pack (rg_sbcs_sbautoincrement),
|
||||
pack (rg_sbcs_sbreadondata),
|
||||
pack (rg_sbcs_sberror),
|
||||
6'b0,
|
||||
pack (rg_sbcs_sbbusyerror),
|
||||
pack (sbbusy),
|
||||
pack (rg_sbcs_sbreadonaddr),
|
||||
pack (rg_sbcs_sbaccess),
|
||||
pack (rg_sbcs_sbautoincrement),
|
||||
pack (rg_sbcs_sbreadondata),
|
||||
pack (rg_sbcs_sberror),
|
||||
`ifdef RV64
|
||||
7'd64, // sbasize -- address size
|
||||
7'd64, // sbasize -- address size
|
||||
`endif
|
||||
`ifdef RV32
|
||||
7'd32, // sbasize -- address size
|
||||
7'd32, // sbasize -- address size
|
||||
`endif
|
||||
1'b0, // sbaccess128
|
||||
1'b0, // sbaccess64
|
||||
1'b1, // sbaccess32
|
||||
1'b1, // sbaccess16
|
||||
1'b1}; // sbaccess8
|
||||
1'b0, // sbaccess128
|
||||
1'b0, // sbaccess64
|
||||
1'b1, // sbaccess32
|
||||
1'b1, // sbaccess16
|
||||
1'b1}; // sbaccess8
|
||||
|
||||
// ----------------
|
||||
// Local defs and help functions
|
||||
@@ -245,16 +245,16 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function Action fa_sbaddress_incr (Bit #(64) addr64);
|
||||
action
|
||||
Bit #(64) next_sbaddress = addr64 + fromInteger (addr_incr);
|
||||
Bit #(64) next_sbaddress = addr64 + fromInteger (addr_incr);
|
||||
`ifdef RV64
|
||||
rg_sbaddress1 <= next_sbaddress [63:32];
|
||||
rg_sbaddress1 <= next_sbaddress [63:32];
|
||||
`else
|
||||
rg_sbaddress1 <= 0;
|
||||
rg_sbaddress1 <= 0;
|
||||
`endif
|
||||
rg_sbaddress0 <= next_sbaddress [31:0];
|
||||
rg_sbaddress0 <= next_sbaddress [31:0];
|
||||
|
||||
if (verbosity != 0)
|
||||
$display (" Increment sbaddr 0x%08h -> 0x%08h", addr64, next_sbaddress);
|
||||
if (verbosity != 0)
|
||||
$display (" Increment sbaddr 0x%08h -> 0x%08h", addr64, next_sbaddress);
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -263,30 +263,30 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function Action fa_fabric_send_read_req (Bit #(64) addr64);
|
||||
action
|
||||
Fabric_Addr fabric_addr = truncate (addr64);
|
||||
let rda = AXI4_Rd_Addr {arid: fabric_default_id,
|
||||
araddr: fabric_addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: fn_DM_sbaccess_to_AXI4_Size (rg_sbcs_sbaccess),
|
||||
arburst: fabric_default_burst,
|
||||
arlock: fabric_default_lock,
|
||||
arcache: fabric_default_arcache,
|
||||
arprot: fabric_default_prot,
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_user};
|
||||
master_xactor.i_rd_addr.enq (rda);
|
||||
Fabric_Addr fabric_addr = truncate (addr64);
|
||||
let rda = AXI4_Rd_Addr {arid: fabric_default_id,
|
||||
araddr: fabric_addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: fn_DM_sbaccess_to_AXI4_Size (rg_sbcs_sbaccess),
|
||||
arburst: fabric_default_burst,
|
||||
arlock: fabric_default_lock,
|
||||
arcache: fabric_default_arcache,
|
||||
arprot: fabric_default_prot,
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_user};
|
||||
master_xactor.i_rd_addr.enq (rda);
|
||||
|
||||
// Save read-address for byte-lane extraction from later response
|
||||
// (since rg_sbaddress may be incremented by then).
|
||||
rg_sbaddress_reading <= addr64;
|
||||
// Save read-address for byte-lane extraction from later response
|
||||
// (since rg_sbaddress may be incremented by then).
|
||||
rg_sbaddress_reading <= addr64;
|
||||
|
||||
rg_sb_state <= SB_READ_FINISH;
|
||||
rg_sb_state <= SB_READ_FINISH;
|
||||
|
||||
if (verbosity != 0) begin
|
||||
$display (" DM_System_Bus.fa_fabric_send_read_req, and => SB_READ_FINISH ");
|
||||
$display (" ", fshow (rda));
|
||||
end
|
||||
if (verbosity != 0) begin
|
||||
$display (" DM_System_Bus.fa_fabric_send_read_req, and => SB_READ_FINISH ");
|
||||
$display (" ", fshow (rda));
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -295,40 +295,40 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function Action fa_fabric_send_write_req (Bit #(64) data64);
|
||||
action
|
||||
match {.fabric_addr,
|
||||
.fabric_data,
|
||||
.fabric_strb,
|
||||
.fabric_size} = fn_to_fabric_write_fields (rg_sbcs_sbaccess, sbaddress, data64);
|
||||
|
||||
// fabric_addr is always fabric-data-width aligned
|
||||
// fabric_data is properly lane-adjusted
|
||||
// fabric_strb identifies the lanes to be written
|
||||
// awsize is always the fabric width
|
||||
match {.fabric_addr,
|
||||
.fabric_data,
|
||||
.fabric_strb,
|
||||
.fabric_size} = fn_to_fabric_write_fields (rg_sbcs_sbaccess, sbaddress, data64);
|
||||
|
||||
// fabric_addr is always fabric-data-width aligned
|
||||
// fabric_data is properly lane-adjusted
|
||||
// fabric_strb identifies the lanes to be written
|
||||
// awsize is always the fabric width
|
||||
|
||||
let wra = AXI4_Wr_Addr {awid: fabric_default_id,
|
||||
awaddr: fabric_addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: fabric_size,
|
||||
awburst: fabric_default_burst,
|
||||
awlock: fabric_default_lock,
|
||||
awcache: fabric_default_awcache,
|
||||
awprot: fabric_default_prot,
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: fabric_default_user};
|
||||
master_xactor.i_wr_addr.enq (wra);
|
||||
let wra = AXI4_Wr_Addr {awid: fabric_default_id,
|
||||
awaddr: fabric_addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: fabric_size,
|
||||
awburst: fabric_default_burst,
|
||||
awlock: fabric_default_lock,
|
||||
awcache: fabric_default_awcache,
|
||||
awprot: fabric_default_prot,
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: fabric_default_user};
|
||||
master_xactor.i_wr_addr.enq (wra);
|
||||
|
||||
let wrd = AXI4_Wr_Data {wdata: fabric_data,
|
||||
wstrb: fabric_strb,
|
||||
wlast: True,
|
||||
wuser: fabric_default_user};
|
||||
master_xactor.i_wr_data.enq (wrd);
|
||||
let wrd = AXI4_Wr_Data {wdata: fabric_data,
|
||||
wstrb: fabric_strb,
|
||||
wlast: True,
|
||||
wuser: fabric_default_user};
|
||||
master_xactor.i_wr_data.enq (wrd);
|
||||
|
||||
if (verbosity != 0) begin
|
||||
$display (" DM_System_Bus.fa_fabric_send_write_req:");
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
end
|
||||
if (verbosity != 0) begin
|
||||
$display (" DM_System_Bus.fa_fabric_send_write_req:");
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -337,54 +337,54 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function Action fa_rg_sbcs_write (DM_Word dm_word);
|
||||
action
|
||||
Bool sbbusyerror = unpack (dm_word [22]);
|
||||
Bool sbreadonaddr = unpack (dm_word [20]);
|
||||
DM_sbaccess sbaccess = unpack (dm_word [19:17]);
|
||||
Bool sbautoincrement = unpack (dm_word [16]);
|
||||
Bool sbreadondata = unpack (dm_word [15]);
|
||||
DM_sberror sberror = unpack (dm_word [14:12]);
|
||||
Bool sbbusyerror = unpack (dm_word [22]);
|
||||
Bool sbreadonaddr = unpack (dm_word [20]);
|
||||
DM_sbaccess sbaccess = unpack (dm_word [19:17]);
|
||||
Bool sbautoincrement = unpack (dm_word [16]);
|
||||
Bool sbreadondata = unpack (dm_word [15]);
|
||||
DM_sberror sberror = unpack (dm_word [14:12]);
|
||||
|
||||
// No-op if not clearing existing sberror
|
||||
if ((rg_sbcs_sberror != DM_SBERROR_NONE) && (sberror == DM_SBERROR_NONE)) begin
|
||||
// Existing error is not being cleared
|
||||
$display ("DM_System_Bus.sbcs_write <= 0x%08h: ERROR", dm_word);
|
||||
$display (" ERROR: existing sberror (0x%0h) is not being cleared.", rg_sbcs_sberror);
|
||||
$display (" Must be cleared to re-enable system bus access.");
|
||||
end
|
||||
// No-op if not clearing existing sberror
|
||||
if ((rg_sbcs_sberror != DM_SBERROR_NONE) && (sberror == DM_SBERROR_NONE)) begin
|
||||
// Existing error is not being cleared
|
||||
$display ("DM_System_Bus.sbcs_write <= 0x%08h: ERROR", dm_word);
|
||||
$display (" ERROR: existing sberror (0x%0h) is not being cleared.", rg_sbcs_sberror);
|
||||
$display (" Must be cleared to re-enable system bus access.");
|
||||
end
|
||||
|
||||
// No-op if not clearing existing sbbusyerror
|
||||
else if (rg_sbcs_sbbusyerror && (! sbbusyerror)) begin
|
||||
$display ("DM_System_Bus.sbcs_write <= 0x%08h: ERROR", dm_word);
|
||||
$display (" ERROR: existing sbbusyerror (%0d) is not being cleared.", rg_sbcs_sbbusyerror);
|
||||
$display (" Must be cleared to re-enable system bus access.");
|
||||
end
|
||||
// No-op if not clearing existing sbbusyerror
|
||||
else if (rg_sbcs_sbbusyerror && (! sbbusyerror)) begin
|
||||
$display ("DM_System_Bus.sbcs_write <= 0x%08h: ERROR", dm_word);
|
||||
$display (" ERROR: existing sbbusyerror (%0d) is not being cleared.", rg_sbcs_sbbusyerror);
|
||||
$display (" Must be cleared to re-enable system bus access.");
|
||||
end
|
||||
|
||||
// Check that requested access size is supported
|
||||
else if ( (sbaccess == DM_SBACCESS_128_BIT)
|
||||
|| (sbaccess == DM_SBACCESS_64_BIT))
|
||||
begin
|
||||
rg_sbcs_sberror <= DM_SBERROR_OTHER;
|
||||
$display ("DM_System_Bus.sbcs_write <= 0x%08h: ERROR", dm_word);
|
||||
$display (" ERROR: sbaccess ", fshow (sbaccess), " not supported");
|
||||
end
|
||||
// Check that requested access size is supported
|
||||
else if ( (sbaccess == DM_SBACCESS_128_BIT)
|
||||
|| (sbaccess == DM_SBACCESS_64_BIT))
|
||||
begin
|
||||
rg_sbcs_sberror <= DM_SBERROR_OTHER;
|
||||
$display ("DM_System_Bus.sbcs_write <= 0x%08h: ERROR", dm_word);
|
||||
$display (" ERROR: sbaccess ", fshow (sbaccess), " not supported");
|
||||
end
|
||||
|
||||
// Ok
|
||||
else begin
|
||||
if (verbosity != 0) begin
|
||||
$display (" DM_System_Bus.sbcs_write: ", fshow_sbcs (dm_word));
|
||||
if (rg_sbcs_sberror != DM_SBERROR_NONE)
|
||||
$display (" Clearing sbcs.sberror");
|
||||
if (rg_sbcs_sbbusyerror)
|
||||
$display (" Clearing sbcs.sbbusyerror");
|
||||
end
|
||||
// Ok
|
||||
else begin
|
||||
if (verbosity != 0) begin
|
||||
$display (" DM_System_Bus.sbcs_write: ", fshow_sbcs (dm_word));
|
||||
if (rg_sbcs_sberror != DM_SBERROR_NONE)
|
||||
$display (" Clearing sbcs.sberror");
|
||||
if (rg_sbcs_sbbusyerror)
|
||||
$display (" Clearing sbcs.sbbusyerror");
|
||||
end
|
||||
|
||||
rg_sbcs_sbbusyerror <= False;
|
||||
rg_sbcs_sbreadonaddr <= sbreadonaddr;
|
||||
rg_sbcs_sbaccess <= sbaccess;
|
||||
rg_sbcs_sbautoincrement <= sbautoincrement;
|
||||
rg_sbcs_sbreadondata <= sbreadondata;
|
||||
rg_sbcs_sberror <= DM_SBERROR_NONE;
|
||||
end
|
||||
rg_sbcs_sbbusyerror <= False;
|
||||
rg_sbcs_sbreadonaddr <= sbreadonaddr;
|
||||
rg_sbcs_sbaccess <= sbaccess;
|
||||
rg_sbcs_sbautoincrement <= sbautoincrement;
|
||||
rg_sbcs_sbreadondata <= sbreadondata;
|
||||
rg_sbcs_sberror <= DM_SBERROR_NONE;
|
||||
end
|
||||
endaction
|
||||
endfunction: fa_rg_sbcs_write
|
||||
|
||||
@@ -393,54 +393,54 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function Action fa_rg_sbaddress_write (DM_Addr dm_addr, DM_Word dm_word);
|
||||
action
|
||||
// Debug announce
|
||||
if (verbosity != 0) begin
|
||||
$write ("DM_System_Bus.sbaddress.write: [0x%08h] <= 0x%08h", dm_addr, dm_word);
|
||||
if (rg_sbcs_sbreadonaddr) begin
|
||||
$write ("; readonaddr");
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
$write ("; autoincrement");
|
||||
end
|
||||
$display ("");
|
||||
end
|
||||
// Debug announce
|
||||
if (verbosity != 0) begin
|
||||
$write ("DM_System_Bus.sbaddress.write: [0x%08h] <= 0x%08h", dm_addr, dm_word);
|
||||
if (rg_sbcs_sbreadonaddr) begin
|
||||
$write ("; readonaddr");
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
$write ("; autoincrement");
|
||||
end
|
||||
$display ("");
|
||||
end
|
||||
|
||||
if (sbbusy) begin
|
||||
$display ("DM_System_Bus.sbaddress.write: busy, setting sbbusyerror");
|
||||
rg_sbcs_sbbusyerror <= True;
|
||||
end
|
||||
if (sbbusy) begin
|
||||
$display ("DM_System_Bus.sbaddress.write: busy, setting sbbusyerror");
|
||||
rg_sbcs_sbbusyerror <= True;
|
||||
end
|
||||
|
||||
else if (rg_sbcs_sbbusyerror)
|
||||
$display ("DM_System_Bus.sbaddress.write: ignoring due to sbbusyerror");
|
||||
else if (rg_sbcs_sbbusyerror)
|
||||
$display ("DM_System_Bus.sbaddress.write: ignoring due to sbbusyerror");
|
||||
|
||||
else if (rg_sbcs_sberror != DM_SBERROR_NONE)
|
||||
$display ("DM_System_Bus.sbaddress.write: ignoring due to sberror = 0x%0h",
|
||||
rg_sbcs_sberror);
|
||||
else if (rg_sbcs_sberror != DM_SBERROR_NONE)
|
||||
$display ("DM_System_Bus.sbaddress.write: ignoring due to sberror = 0x%0h",
|
||||
rg_sbcs_sberror);
|
||||
|
||||
else if (dm_addr == dm_addr_sbaddress0) begin
|
||||
Bit #(64) addr64 = { rg_sbaddress1, dm_word };
|
||||
if (rg_sbcs_sbreadonaddr) begin
|
||||
fa_fabric_send_read_req (addr64);
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
fa_sbaddress_incr (addr64);
|
||||
else
|
||||
rg_sbaddress0 <= dm_word;
|
||||
end
|
||||
else
|
||||
rg_sbaddress0 <= dm_word;
|
||||
end
|
||||
else if (dm_addr == dm_addr_sbaddress0) begin
|
||||
Bit #(64) addr64 = { rg_sbaddress1, dm_word };
|
||||
if (rg_sbcs_sbreadonaddr) begin
|
||||
fa_fabric_send_read_req (addr64);
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
fa_sbaddress_incr (addr64);
|
||||
else
|
||||
rg_sbaddress0 <= dm_word;
|
||||
end
|
||||
else
|
||||
rg_sbaddress0 <= dm_word;
|
||||
end
|
||||
|
||||
else begin // (dm_addr == dm_addr_sbaddress1)
|
||||
else begin // (dm_addr == dm_addr_sbaddress1)
|
||||
`ifdef RV32
|
||||
rg_sbaddress1 <= 0;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.write: [sbaddress1] <= 0 (RV32: ignoring arg value 0x%08h)",
|
||||
dm_word);
|
||||
rg_sbaddress1 <= 0;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.write: [sbaddress1] <= 0 (RV32: ignoring arg value 0x%08h)",
|
||||
dm_word);
|
||||
`else
|
||||
rg_sbaddress1 <= dm_word;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.write: [sbaddress1] <= 0x%08h", dm_word);
|
||||
rg_sbaddress1 <= dm_word;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.write: [sbaddress1] <= 0x%08h", dm_word);
|
||||
`endif
|
||||
end
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -449,35 +449,35 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function ActionValue #(DM_Word) fav_rg_sbdata_read (DM_Addr dm_addr);
|
||||
actionvalue
|
||||
DM_Word result = 0;
|
||||
if (sbbusy) begin
|
||||
$display ("DM_System_Bus.sbdata.read: busy, setting sbbusyerror");
|
||||
rg_sbcs_sbbusyerror <= True;
|
||||
end
|
||||
DM_Word result = 0;
|
||||
if (sbbusy) begin
|
||||
$display ("DM_System_Bus.sbdata.read: busy, setting sbbusyerror");
|
||||
rg_sbcs_sbbusyerror <= True;
|
||||
end
|
||||
|
||||
else if (rg_sbcs_sbbusyerror)
|
||||
$display ("DM_System_Bus.sbdata.read: ignoring due to sbbusyerror");
|
||||
else if (rg_sbcs_sbbusyerror)
|
||||
$display ("DM_System_Bus.sbdata.read: ignoring due to sbbusyerror");
|
||||
|
||||
else if (rg_sbcs_sberror != DM_SBERROR_NONE)
|
||||
$display ("DM_System_Bus.sbdata.read: ignoring due to sberror = 0x%0h", rg_sbcs_sberror);
|
||||
else if (rg_sbcs_sberror != DM_SBERROR_NONE)
|
||||
$display ("DM_System_Bus.sbdata.read: ignoring due to sberror = 0x%0h", rg_sbcs_sberror);
|
||||
|
||||
else begin
|
||||
if (dm_addr == dm_addr_sbdata0)
|
||||
result = rg_sbdata0;
|
||||
/* FUTURE: when supporting DM_SBACCESS_64_BIT
|
||||
else if (dm_addr == dm_addr_sbdata1)
|
||||
result = rg_sbdata1;
|
||||
*/
|
||||
else begin
|
||||
if (dm_addr == dm_addr_sbdata0)
|
||||
result = rg_sbdata0;
|
||||
/* FUTURE: when supporting DM_SBACCESS_64_BIT
|
||||
else if (dm_addr == dm_addr_sbdata1)
|
||||
result = rg_sbdata1;
|
||||
*/
|
||||
|
||||
// Increment sbaddress if needed
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
fa_sbaddress_incr (sbaddress);
|
||||
// Increment sbaddress if needed
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
fa_sbaddress_incr (sbaddress);
|
||||
|
||||
// Auto-read next data if needed
|
||||
if (rg_sbcs_sbreadondata && (dm_addr == dm_addr_sbdata0))
|
||||
fa_fabric_send_read_req (sbaddress);
|
||||
end
|
||||
return result;
|
||||
// Auto-read next data if needed
|
||||
if (rg_sbcs_sbreadondata && (dm_addr == dm_addr_sbdata0))
|
||||
fa_fabric_send_read_req (sbaddress);
|
||||
end
|
||||
return result;
|
||||
endactionvalue
|
||||
endfunction
|
||||
|
||||
@@ -487,19 +487,19 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
(* descending_urgency = "rl_sb_read_finish, reset" *)
|
||||
(* descending_urgency = "rl_sb_read_finish, write" *)
|
||||
rule rl_sb_read_finish ( (rg_sb_state == SB_READ_FINISH)
|
||||
&& (rg_sbcs_sberror == DM_SBERROR_NONE));
|
||||
&& (rg_sbcs_sberror == DM_SBERROR_NONE));
|
||||
let rdr <- pop_o (master_xactor.o_rd_data);
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.rule_sb_read_finish: rdr = ", fshow (rdr));
|
||||
$display ("DM_System_Bus.rule_sb_read_finish: rdr = ", fshow (rdr));
|
||||
|
||||
// Extract relevant bytes from fabric data
|
||||
Bit #(64) rdata64 = zeroExtend (rdr.rdata);
|
||||
Bit #(64) data = fn_extract_and_extend_bytes (rg_sbcs_sbaccess, rg_sbaddress_reading, rdata64);
|
||||
|
||||
if (rdr.rresp != axi4_resp_okay) begin
|
||||
$display ("DM_System_Bus.rule_sb_read_finish: setting rg_sbcs_sberror to DM_SBERROR_OTHER\n");
|
||||
$display (" rdr = ", fshow (rdr));
|
||||
rg_sbcs_sberror <= DM_SBERROR_OTHER;
|
||||
$display ("DM_System_Bus.rule_sb_read_finish: setting rg_sbcs_sberror to DM_SBERROR_OTHER\n");
|
||||
$display (" rdr = ", fshow (rdr));
|
||||
rg_sbcs_sberror <= DM_SBERROR_OTHER;
|
||||
end
|
||||
|
||||
rg_sbdata0 <= data [31:0];
|
||||
@@ -508,10 +508,10 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
*/
|
||||
|
||||
if (verbosity != 0) begin
|
||||
$display ("DM_System_Bus.rule_sb_read_finish: addr 0x%0h, sbaccess %0d (%0d bytes)",
|
||||
rg_sbaddress_reading, rg_sbcs_sbaccess, addr_incr);
|
||||
$display (" rg_sbdata0 <= 0x%0h", data);
|
||||
$display (" module state => SB_NOTBUSY");
|
||||
$display ("DM_System_Bus.rule_sb_read_finish: addr 0x%0h, sbaccess %0d (%0d bytes)",
|
||||
rg_sbaddress_reading, rg_sbcs_sbaccess, addr_incr);
|
||||
$display (" rg_sbdata0 <= 0x%0h", data);
|
||||
$display (" module state => SB_NOTBUSY");
|
||||
end
|
||||
|
||||
rg_sb_state <= SB_NOTBUSY;
|
||||
@@ -522,41 +522,41 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
function Action fa_rg_sbdata_write (DM_Addr dm_addr, DM_Word dm_word);
|
||||
action
|
||||
if (sbbusy) begin
|
||||
$display ("DM_System_Bus.sbdata.write: busy, setting sbbusyerror");
|
||||
rg_sbcs_sbbusyerror <= True;
|
||||
end
|
||||
if (sbbusy) begin
|
||||
$display ("DM_System_Bus.sbdata.write: busy, setting sbbusyerror");
|
||||
rg_sbcs_sbbusyerror <= True;
|
||||
end
|
||||
|
||||
else if (rg_sbcs_sbbusyerror) begin
|
||||
$display ("DM_System_Bus.sbdata.write: ignoring due to sbbusyerror");
|
||||
end
|
||||
else if (rg_sbcs_sbbusyerror) begin
|
||||
$display ("DM_System_Bus.sbdata.write: ignoring due to sbbusyerror");
|
||||
end
|
||||
|
||||
else if (rg_sbcs_sberror != DM_SBERROR_NONE) begin
|
||||
$display ("DM_System_Bus.sbdata.write: ignoring due to sberror = 0x%0h",
|
||||
rg_sbcs_sberror);
|
||||
end
|
||||
else if (rg_sbcs_sberror != DM_SBERROR_NONE) begin
|
||||
$display ("DM_System_Bus.sbdata.write: ignoring due to sberror = 0x%0h",
|
||||
rg_sbcs_sberror);
|
||||
end
|
||||
|
||||
else begin
|
||||
if (verbosity != 0)
|
||||
$display (" DM_System_Bus.fa_rg_sbdata_write: dm_addr 0x%08h dm_word 0x%08h",
|
||||
dm_addr, dm_word);
|
||||
else begin
|
||||
if (verbosity != 0)
|
||||
$display (" DM_System_Bus.fa_rg_sbdata_write: dm_addr 0x%08h dm_word 0x%08h",
|
||||
dm_addr, dm_word);
|
||||
|
||||
if (dm_addr == dm_addr_sbdata0)
|
||||
rg_sbdata0 <= dm_word;
|
||||
/* FUTURE: when supporting DM_SBACCESS_64_BIT
|
||||
else if (dm_addr == dm_addr_sbdata1)
|
||||
rg_sbdata1 <= dm_word;
|
||||
*/
|
||||
if (dm_addr == dm_addr_sbdata0)
|
||||
rg_sbdata0 <= dm_word;
|
||||
/* FUTURE: when supporting DM_SBACCESS_64_BIT
|
||||
else if (dm_addr == dm_addr_sbdata1)
|
||||
rg_sbdata1 <= dm_word;
|
||||
*/
|
||||
|
||||
// Initiate system bus write if writing to sbdata0
|
||||
if (dm_addr == dm_addr_sbdata0) begin
|
||||
fa_fabric_send_write_req (zeroExtend (dm_word));
|
||||
// Initiate system bus write if writing to sbdata0
|
||||
if (dm_addr == dm_addr_sbdata0) begin
|
||||
fa_fabric_send_write_req (zeroExtend (dm_word));
|
||||
|
||||
// Increment sbaddr ifneeded
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
fa_sbaddress_incr (sbaddress);
|
||||
end
|
||||
end
|
||||
// Increment sbaddr ifneeded
|
||||
if (rg_sbcs_sbautoincrement)
|
||||
fa_sbaddress_incr (sbaddress);
|
||||
end
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -566,7 +566,7 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
rule rl_sb_write_response;
|
||||
let wrr <- pop_o (master_xactor.o_wr_resp);
|
||||
if (wrr.bresp != axi4_resp_okay)
|
||||
rg_sbcs_sberror <= DM_SBERROR_OTHER;
|
||||
rg_sbcs_sberror <= DM_SBERROR_OTHER;
|
||||
endrule
|
||||
|
||||
// ================================================================
|
||||
@@ -589,7 +589,7 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
rg_sbdata0 <= 0;
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus: reset");
|
||||
$display ("DM_System_Bus: reset");
|
||||
endmethod
|
||||
|
||||
// ----------------
|
||||
@@ -600,55 +600,55 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
// workable for a true JTAG transport.
|
||||
method ActionValue #(DM_Word) av_read (DM_Addr dm_addr) if (!sbbusy);
|
||||
actionvalue
|
||||
DM_Word dm_word = 0;
|
||||
DM_Word dm_word = 0;
|
||||
|
||||
if (dm_addr == dm_addr_sbcs) begin
|
||||
dm_word = virt_rg_sbcs;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.read: [sbcs] => ", fshow_sbcs (dm_word));
|
||||
end
|
||||
if (dm_addr == dm_addr_sbcs) begin
|
||||
dm_word = virt_rg_sbcs;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.read: [sbcs] => ", fshow_sbcs (dm_word));
|
||||
end
|
||||
|
||||
else if (dm_addr == dm_addr_sbaddress0) begin
|
||||
dm_word = rg_sbaddress0;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.read: [sbaddress0] => 0x%08h", dm_word);
|
||||
end
|
||||
else if (dm_addr == dm_addr_sbaddress0) begin
|
||||
dm_word = rg_sbaddress0;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.read: [sbaddress0] => 0x%08h", dm_word);
|
||||
end
|
||||
|
||||
else if (dm_addr == dm_addr_sbaddress1) begin
|
||||
dm_word = rg_sbaddress1;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.read: [sbaddress1] => 0x%08h", dm_word);
|
||||
end
|
||||
else if (dm_addr == dm_addr_sbaddress1) begin
|
||||
dm_word = rg_sbaddress1;
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.read: [sbaddress1] => 0x%08h", dm_word);
|
||||
end
|
||||
|
||||
else if (dm_addr == dm_addr_sbdata0) begin
|
||||
dm_word <- fav_rg_sbdata_read (dm_addr_sbdata0);
|
||||
end
|
||||
else if (dm_addr == dm_addr_sbdata0) begin
|
||||
dm_word <- fav_rg_sbdata_read (dm_addr_sbdata0);
|
||||
end
|
||||
|
||||
else begin
|
||||
// Unsupported dm address
|
||||
dm_word = 0;
|
||||
$display ("DM_System_Bus.read: [", fshow_dm_addr (dm_addr), "] not supported");
|
||||
end
|
||||
return dm_word;
|
||||
else begin
|
||||
// Unsupported dm address
|
||||
dm_word = 0;
|
||||
$display ("DM_System_Bus.read: [", fshow_dm_addr (dm_addr), "] not supported");
|
||||
end
|
||||
return dm_word;
|
||||
endactionvalue
|
||||
endmethod
|
||||
|
||||
method Action write (DM_Addr dm_addr, DM_Word dm_word);
|
||||
action
|
||||
if (dm_addr == dm_addr_sbcs)
|
||||
if (dm_addr == dm_addr_sbcs)
|
||||
fa_rg_sbcs_write (dm_word);
|
||||
|
||||
else if ((dm_addr == dm_addr_sbaddress0) || (dm_addr == dm_addr_sbaddress1))
|
||||
fa_rg_sbaddress_write (dm_addr, dm_word);
|
||||
else if ((dm_addr == dm_addr_sbaddress0) || (dm_addr == dm_addr_sbaddress1))
|
||||
fa_rg_sbaddress_write (dm_addr, dm_word);
|
||||
|
||||
else if (dm_addr == dm_addr_sbdata0) // FUTURE: || (dm_addr == dm_addr_sbdata1)
|
||||
fa_rg_sbdata_write (dm_addr, dm_word);
|
||||
else if (dm_addr == dm_addr_sbdata0) // FUTURE: || (dm_addr == dm_addr_sbdata1)
|
||||
fa_rg_sbdata_write (dm_addr, dm_word);
|
||||
|
||||
else begin
|
||||
// Unsupported dm_addr
|
||||
let addr_name = fshow_dm_addr (dm_addr);
|
||||
$display ("DM_System_Bus.write: [", addr_name, "] <= 0x%08h; addr not supported", dm_word);
|
||||
end
|
||||
else begin
|
||||
// Unsupported dm_addr
|
||||
let addr_name = fshow_dm_addr (dm_addr);
|
||||
$display ("DM_System_Bus.write: [", addr_name, "] <= 0x%08h; addr not supported", dm_word);
|
||||
end
|
||||
endaction
|
||||
endmethod
|
||||
|
||||
|
||||
@@ -155,127 +155,127 @@ module mkDebug_Module (Debug_Module_IFC);
|
||||
|
||||
interface DMI dmi;
|
||||
method Action read_addr (DM_Addr dm_addr);
|
||||
f_read_addr.enq(dm_addr);
|
||||
f_read_addr.enq(dm_addr);
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.DMI read: dm_addr 0x%0h", cur_cycle, dm_addr);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.DMI read: dm_addr 0x%0h", cur_cycle, dm_addr);
|
||||
endmethod
|
||||
|
||||
method ActionValue #(DM_Word) read_data;
|
||||
let dm_addr = f_read_addr.first;
|
||||
f_read_addr.deq;
|
||||
let dm_addr = f_read_addr.first;
|
||||
f_read_addr.deq;
|
||||
|
||||
DM_Word dm_word = ?;
|
||||
DM_Word dm_word = ?;
|
||||
|
||||
if ( (dm_addr == dm_addr_dmcontrol)
|
||||
|| (dm_addr == dm_addr_dmstatus)
|
||||
|| (dm_addr == dm_addr_hartinfo)
|
||||
|| (dm_addr == dm_addr_haltsum)
|
||||
|| (dm_addr == dm_addr_hawindowsel)
|
||||
|| (dm_addr == dm_addr_hawindow)
|
||||
|| (dm_addr == dm_addr_devtreeaddr0)
|
||||
|| (dm_addr == dm_addr_authdata)
|
||||
|| (dm_addr == dm_addr_haltregion0)
|
||||
|| (dm_addr == dm_addr_haltregion31)
|
||||
|| (dm_addr == dm_addr_verbosity))
|
||||
if ( (dm_addr == dm_addr_dmcontrol)
|
||||
|| (dm_addr == dm_addr_dmstatus)
|
||||
|| (dm_addr == dm_addr_hartinfo)
|
||||
|| (dm_addr == dm_addr_haltsum)
|
||||
|| (dm_addr == dm_addr_hawindowsel)
|
||||
|| (dm_addr == dm_addr_hawindow)
|
||||
|| (dm_addr == dm_addr_devtreeaddr0)
|
||||
|| (dm_addr == dm_addr_authdata)
|
||||
|| (dm_addr == dm_addr_haltregion0)
|
||||
|| (dm_addr == dm_addr_haltregion31)
|
||||
|| (dm_addr == dm_addr_verbosity))
|
||||
|
||||
dm_word <- dm_run_control.av_read (dm_addr);
|
||||
dm_word <- dm_run_control.av_read (dm_addr);
|
||||
|
||||
else if ( (dm_addr == dm_addr_abstractcs)
|
||||
|| (dm_addr == dm_addr_command)
|
||||
|| (dm_addr == dm_addr_data0)
|
||||
|| (dm_addr == dm_addr_data1)
|
||||
|| (dm_addr == dm_addr_data2)
|
||||
|| (dm_addr == dm_addr_data3)
|
||||
|| (dm_addr == dm_addr_data4)
|
||||
|| (dm_addr == dm_addr_data5)
|
||||
|| (dm_addr == dm_addr_data6)
|
||||
|| (dm_addr == dm_addr_data7)
|
||||
|| (dm_addr == dm_addr_data8)
|
||||
|| (dm_addr == dm_addr_data9)
|
||||
|| (dm_addr == dm_addr_data10)
|
||||
|| (dm_addr == dm_addr_data11)
|
||||
|| (dm_addr == dm_addr_abstractauto)
|
||||
|| (dm_addr == dm_addr_progbuf0))
|
||||
else if ( (dm_addr == dm_addr_abstractcs)
|
||||
|| (dm_addr == dm_addr_command)
|
||||
|| (dm_addr == dm_addr_data0)
|
||||
|| (dm_addr == dm_addr_data1)
|
||||
|| (dm_addr == dm_addr_data2)
|
||||
|| (dm_addr == dm_addr_data3)
|
||||
|| (dm_addr == dm_addr_data4)
|
||||
|| (dm_addr == dm_addr_data5)
|
||||
|| (dm_addr == dm_addr_data6)
|
||||
|| (dm_addr == dm_addr_data7)
|
||||
|| (dm_addr == dm_addr_data8)
|
||||
|| (dm_addr == dm_addr_data9)
|
||||
|| (dm_addr == dm_addr_data10)
|
||||
|| (dm_addr == dm_addr_data11)
|
||||
|| (dm_addr == dm_addr_abstractauto)
|
||||
|| (dm_addr == dm_addr_progbuf0))
|
||||
|
||||
dm_word <- dm_abstract_commands.av_read (dm_addr);
|
||||
dm_word <- dm_abstract_commands.av_read (dm_addr);
|
||||
|
||||
else if ( (dm_addr == dm_addr_sbcs)
|
||||
|| (dm_addr == dm_addr_sbaddress0)
|
||||
|| (dm_addr == dm_addr_sbaddress1)
|
||||
|| (dm_addr == dm_addr_sbaddress2)
|
||||
|| (dm_addr == dm_addr_sbdata0)
|
||||
|| (dm_addr == dm_addr_sbdata1)
|
||||
|| (dm_addr == dm_addr_sbdata2)
|
||||
|| (dm_addr == dm_addr_sbdata3))
|
||||
else if ( (dm_addr == dm_addr_sbcs)
|
||||
|| (dm_addr == dm_addr_sbaddress0)
|
||||
|| (dm_addr == dm_addr_sbaddress1)
|
||||
|| (dm_addr == dm_addr_sbaddress2)
|
||||
|| (dm_addr == dm_addr_sbdata0)
|
||||
|| (dm_addr == dm_addr_sbdata1)
|
||||
|| (dm_addr == dm_addr_sbdata2)
|
||||
|| (dm_addr == dm_addr_sbdata3))
|
||||
|
||||
dm_word <- dm_system_bus.av_read (dm_addr);
|
||||
dm_word <- dm_system_bus.av_read (dm_addr);
|
||||
|
||||
else begin
|
||||
// TODO: set error status?
|
||||
dm_word = 0;
|
||||
end
|
||||
else begin
|
||||
// TODO: set error status?
|
||||
dm_word = 0;
|
||||
end
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.DMI read response: dm_addr 0x%0h, dm_word 0x%0h",
|
||||
cur_cycle, dm_addr, dm_word);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.DMI read response: dm_addr 0x%0h, dm_word 0x%0h",
|
||||
cur_cycle, dm_addr, dm_word);
|
||||
|
||||
return dm_word;
|
||||
return dm_word;
|
||||
endmethod
|
||||
|
||||
method Action write (DM_Addr dm_addr, DM_Word dm_word);
|
||||
if ( (dm_addr == dm_addr_dmcontrol)
|
||||
|| (dm_addr == dm_addr_dmstatus)
|
||||
|| (dm_addr == dm_addr_hartinfo)
|
||||
|| (dm_addr == dm_addr_haltsum)
|
||||
|| (dm_addr == dm_addr_hawindowsel)
|
||||
|| (dm_addr == dm_addr_hawindow)
|
||||
|| (dm_addr == dm_addr_devtreeaddr0)
|
||||
|| (dm_addr == dm_addr_authdata)
|
||||
|| (dm_addr == dm_addr_haltregion0)
|
||||
|| (dm_addr == dm_addr_haltregion31)
|
||||
|| (dm_addr == dm_addr_verbosity))
|
||||
if ( (dm_addr == dm_addr_dmcontrol)
|
||||
|| (dm_addr == dm_addr_dmstatus)
|
||||
|| (dm_addr == dm_addr_hartinfo)
|
||||
|| (dm_addr == dm_addr_haltsum)
|
||||
|| (dm_addr == dm_addr_hawindowsel)
|
||||
|| (dm_addr == dm_addr_hawindow)
|
||||
|| (dm_addr == dm_addr_devtreeaddr0)
|
||||
|| (dm_addr == dm_addr_authdata)
|
||||
|| (dm_addr == dm_addr_haltregion0)
|
||||
|| (dm_addr == dm_addr_haltregion31)
|
||||
|| (dm_addr == dm_addr_verbosity))
|
||||
|
||||
dm_run_control.write (dm_addr, dm_word);
|
||||
dm_run_control.write (dm_addr, dm_word);
|
||||
|
||||
else if ( (dm_addr == dm_addr_abstractcs)
|
||||
|| (dm_addr == dm_addr_command)
|
||||
|| (dm_addr == dm_addr_data0)
|
||||
|| (dm_addr == dm_addr_data1)
|
||||
|| (dm_addr == dm_addr_data2)
|
||||
|| (dm_addr == dm_addr_data3)
|
||||
|| (dm_addr == dm_addr_data4)
|
||||
|| (dm_addr == dm_addr_data5)
|
||||
|| (dm_addr == dm_addr_data6)
|
||||
|| (dm_addr == dm_addr_data7)
|
||||
|| (dm_addr == dm_addr_data8)
|
||||
|| (dm_addr == dm_addr_data9)
|
||||
|| (dm_addr == dm_addr_data10)
|
||||
|| (dm_addr == dm_addr_data11)
|
||||
|| (dm_addr == dm_addr_abstractauto)
|
||||
|| (dm_addr == dm_addr_progbuf0))
|
||||
else if ( (dm_addr == dm_addr_abstractcs)
|
||||
|| (dm_addr == dm_addr_command)
|
||||
|| (dm_addr == dm_addr_data0)
|
||||
|| (dm_addr == dm_addr_data1)
|
||||
|| (dm_addr == dm_addr_data2)
|
||||
|| (dm_addr == dm_addr_data3)
|
||||
|| (dm_addr == dm_addr_data4)
|
||||
|| (dm_addr == dm_addr_data5)
|
||||
|| (dm_addr == dm_addr_data6)
|
||||
|| (dm_addr == dm_addr_data7)
|
||||
|| (dm_addr == dm_addr_data8)
|
||||
|| (dm_addr == dm_addr_data9)
|
||||
|| (dm_addr == dm_addr_data10)
|
||||
|| (dm_addr == dm_addr_data11)
|
||||
|| (dm_addr == dm_addr_abstractauto)
|
||||
|| (dm_addr == dm_addr_progbuf0))
|
||||
|
||||
dm_abstract_commands.write (dm_addr, dm_word);
|
||||
dm_abstract_commands.write (dm_addr, dm_word);
|
||||
|
||||
else if ( (dm_addr == dm_addr_sbcs)
|
||||
|| (dm_addr == dm_addr_sbaddress0)
|
||||
|| (dm_addr == dm_addr_sbaddress1)
|
||||
|| (dm_addr == dm_addr_sbaddress2)
|
||||
|| (dm_addr == dm_addr_sbdata0)
|
||||
|| (dm_addr == dm_addr_sbdata1)
|
||||
|| (dm_addr == dm_addr_sbdata2)
|
||||
|| (dm_addr == dm_addr_sbdata3))
|
||||
else if ( (dm_addr == dm_addr_sbcs)
|
||||
|| (dm_addr == dm_addr_sbaddress0)
|
||||
|| (dm_addr == dm_addr_sbaddress1)
|
||||
|| (dm_addr == dm_addr_sbaddress2)
|
||||
|| (dm_addr == dm_addr_sbdata0)
|
||||
|| (dm_addr == dm_addr_sbdata1)
|
||||
|| (dm_addr == dm_addr_sbdata2)
|
||||
|| (dm_addr == dm_addr_sbdata3))
|
||||
|
||||
dm_system_bus.write (dm_addr, dm_word);
|
||||
dm_system_bus.write (dm_addr, dm_word);
|
||||
|
||||
else begin
|
||||
// TODO: set error status?
|
||||
noAction;
|
||||
end
|
||||
else begin
|
||||
// TODO: set error status?
|
||||
noAction;
|
||||
end
|
||||
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.DMI write: dm_addr 0x%0h, dm_word 0x%0h",
|
||||
cur_cycle, dm_addr, dm_word);
|
||||
if (verbosity != 0)
|
||||
$display ("%0d: %m.DMI write: dm_addr 0x%0h, dm_word 0x%0h",
|
||||
cur_cycle, dm_addr, dm_word);
|
||||
endmethod
|
||||
endinterface
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@ TOPMODULE = mk$(TOP)
|
||||
# BSCFLAGS = -keep-fires -aggressive-conditions -no-warn-action-shadowing -no-inline-rwire
|
||||
# BSCFLAGS = -keep-fires -aggressive-conditions -no-inline-rwire -show-range-conflict -show-schedule
|
||||
BSCFLAGS = -D RV32 \
|
||||
-keep-fires \
|
||||
-aggressive-conditions \
|
||||
-suppress-warnings G0020 \
|
||||
-show-schedule
|
||||
-keep-fires \
|
||||
-aggressive-conditions \
|
||||
-suppress-warnings G0020 \
|
||||
-show-schedule
|
||||
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
@@ -26,28 +26,28 @@ BSCDIRS_BSIM = -simdir build_bsim -bdir build -info-dir build
|
||||
BSCPATH_BSIM = -p .:..:$(ISA_DECLS_DIR):$(TRX_DIR):$(ADDL_LIBS_DIR):%/Prelude:%/Libraries
|
||||
|
||||
build_bsim:
|
||||
mkdir -p $@
|
||||
mkdir -p $@
|
||||
|
||||
build:
|
||||
mkdir -p $@
|
||||
mkdir -p $@
|
||||
|
||||
.PHONY: compile
|
||||
compile: build_bsim build
|
||||
@echo Compiling...
|
||||
bsc -u -sim $(BSCDIRS_BSIM) $(BSCFLAGS) $(BSCPATH_BSIM) $(TOPFILE)
|
||||
@echo Compilation finished
|
||||
@echo Compiling...
|
||||
bsc -u -sim $(BSCDIRS_BSIM) $(BSCFLAGS) $(BSCPATH_BSIM) $(TOPFILE)
|
||||
@echo Compilation finished
|
||||
|
||||
.PHONY: link
|
||||
link:
|
||||
@echo Linking...
|
||||
bsc -e $(TOPMODULE) $(BSCFLAGS) -parallel-sim-link 8 -sim -o ./$(TOP)_bsim_exe $(BSCDIRS_BSIM) $(BSCPATH_BSIM)
|
||||
@echo Linking finished
|
||||
@echo Linking...
|
||||
bsc -e $(TOPMODULE) $(BSCFLAGS) -parallel-sim-link 8 -sim -o ./$(TOP)_bsim_exe $(BSCDIRS_BSIM) $(BSCPATH_BSIM)
|
||||
@echo Linking finished
|
||||
|
||||
.PHONY: simulate
|
||||
simulate:
|
||||
@echo Simulation...
|
||||
logsave bsim.log ./$(TOP)_bsim_exe -V
|
||||
@echo Simulation finished
|
||||
@echo Simulation...
|
||||
logsave bsim.log ./$(TOP)_bsim_exe -V
|
||||
@echo Simulation finished
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# FOR VERILOG
|
||||
@@ -61,34 +61,34 @@ VSIM ?= cvc
|
||||
# VSIM ?= iverilog
|
||||
|
||||
build_v:
|
||||
mkdir -p $@
|
||||
mkdir -p $@
|
||||
|
||||
verilog:
|
||||
mkdir -p $@
|
||||
mkdir -p $@
|
||||
|
||||
.PHONY: rtl
|
||||
rtl: build_v verilog
|
||||
@echo Verilog generation ...
|
||||
bsc -u -elab -verilog $(BSCDIRS_V) $(BSCFLAGS) $(BSCPATH_V) $(TOPFILE)
|
||||
@echo Verilog generation finished
|
||||
@echo Verilog generation ...
|
||||
bsc -u -elab -verilog $(BSCDIRS_V) $(BSCFLAGS) $(BSCPATH_V) $(TOPFILE)
|
||||
@echo Verilog generation finished
|
||||
|
||||
.PHONY: vlink
|
||||
vlink:
|
||||
bsc -v -e $(TOPMODULE) -verilog -o ./out_v -vdir verilog -vsim $(VSIM) -keep-fires \
|
||||
verilog/$(TOPMODULE).v
|
||||
bsc -v -e $(TOPMODULE) -verilog -o ./out_v -vdir verilog -vsim $(VSIM) -keep-fires \
|
||||
verilog/$(TOPMODULE).v
|
||||
|
||||
.PHONY: vsim
|
||||
vsim:
|
||||
@echo Simulation...
|
||||
./out_v
|
||||
@echo Simulation finished
|
||||
@echo Simulation...
|
||||
./out_v
|
||||
@echo Simulation finished
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f *~ src_*/*~ src_*/*.o build/* build_bsim/* build_v/* *.cxx *.h *.o
|
||||
rm -f *~ src_*/*~ src_*/*.o build/* build_bsim/* build_v/* *.cxx *.h *.o
|
||||
|
||||
.PHONY: full_clean
|
||||
full_clean: clean
|
||||
rm -r -f *_bsim_exe *.so out_v verilog build build_bsim dump.vcd bsim.log
|
||||
rm -r -f *_bsim_exe *.so out_v verilog build build_bsim dump.vcd bsim.log
|
||||
|
||||
@@ -46,8 +46,8 @@ module mkTestbench (Empty);
|
||||
|
||||
rule rl_count_cycles;
|
||||
if (rg_cycle == fromInteger (100)) begin
|
||||
$display ("Testench: stopping at cycle %0d", cycle_limit);
|
||||
$finish (0);
|
||||
$display ("Testench: stopping at cycle %0d", cycle_limit);
|
||||
$finish (0);
|
||||
end
|
||||
rg_cycle <= rg_cycle +1;
|
||||
endrule
|
||||
@@ -90,8 +90,8 @@ module mkTestbench (Empty);
|
||||
let rda <- pop_o (dm.master.fo_rda);
|
||||
let data = rda.addr + 2; // Bogus data, for now
|
||||
let rdr = TRX_RdR {trans_id: rda.trans_id,
|
||||
status : TRX_OKAY,
|
||||
data : data};
|
||||
status : TRX_OKAY,
|
||||
data : data};
|
||||
dm.master.fi_rdr.enq (rdr);
|
||||
$display ("Testbench: memory read [0x%08h] => 0x%08h", rda.addr, data);
|
||||
endrule
|
||||
@@ -100,7 +100,7 @@ module mkTestbench (Empty);
|
||||
let wra <- pop_o (dm.master.fo_wra);
|
||||
let wrd <- pop_o (dm.master.fo_wrd);
|
||||
let wrr = TRX_WrR {trans_id: wra.trans_id,
|
||||
status : TRX_OKAY};
|
||||
status : TRX_OKAY};
|
||||
dm.master.fi_wrr.enq (wrr);
|
||||
$display ("Testbench: memory write [0x%08h] <= 0x%08h", wra.addr, wrd.data);
|
||||
endrule
|
||||
@@ -114,34 +114,34 @@ module mkTestbench (Empty);
|
||||
function Stmt fn_stmt_read_reg (Bit #(16) regno);
|
||||
return
|
||||
seq
|
||||
$display ("----------------\nRead RISC-V reg");
|
||||
// Clear any prior error status
|
||||
dm.write (dm_addr_abstractcs, fn_mk_abstractcs (dm_cmderr_w1c));
|
||||
// Perform the read
|
||||
dm.write (dm_addr_command,
|
||||
fn_mk_command_access_reg (DM_COMMAND_ACCESS_REG_SIZE_LOWER32,
|
||||
False, // postexec
|
||||
True, // transfer
|
||||
False, // write
|
||||
regno));
|
||||
// Read status to check no error
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
while (fn_abstractcs_busy (rg_abstractcs)) seq
|
||||
$display ("Testbench: read reg: busy");
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
endseq
|
||||
if (fn_abstractcs_cmderr (rg_abstractcs) != DM_ABSTRACTCS_CMDERR_NONE)
|
||||
$display ("Testbench: read reg => ", fshow (fn_abstractcs_cmderr (rg_abstractcs)));
|
||||
else action
|
||||
let x <- dm.av_read (dm_addr_data0);
|
||||
$display ("Testbench: read reg => 0x%08h", x);
|
||||
endaction
|
||||
$display ("----------------\nRead RISC-V reg");
|
||||
// Clear any prior error status
|
||||
dm.write (dm_addr_abstractcs, fn_mk_abstractcs (dm_cmderr_w1c));
|
||||
// Perform the read
|
||||
dm.write (dm_addr_command,
|
||||
fn_mk_command_access_reg (DM_COMMAND_ACCESS_REG_SIZE_LOWER32,
|
||||
False, // postexec
|
||||
True, // transfer
|
||||
False, // write
|
||||
regno));
|
||||
// Read status to check no error
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
while (fn_abstractcs_busy (rg_abstractcs)) seq
|
||||
$display ("Testbench: read reg: busy");
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
endseq
|
||||
if (fn_abstractcs_cmderr (rg_abstractcs) != DM_ABSTRACTCS_CMDERR_NONE)
|
||||
$display ("Testbench: read reg => ", fshow (fn_abstractcs_cmderr (rg_abstractcs)));
|
||||
else action
|
||||
let x <- dm.av_read (dm_addr_data0);
|
||||
$display ("Testbench: read reg => 0x%08h", x);
|
||||
endaction
|
||||
endseq;
|
||||
endfunction
|
||||
|
||||
@@ -149,31 +149,31 @@ module mkTestbench (Empty);
|
||||
function Stmt fn_stmt_write_reg (Bit #(16) regno, Bit #(32) data);
|
||||
return
|
||||
seq
|
||||
$display ("----------------\nWrite RISC-V reg");
|
||||
// Clear any prior error status
|
||||
dm.write (dm_addr_abstractcs, fn_mk_abstractcs (dm_cmderr_w1c));
|
||||
// Write data0
|
||||
dm.write (dm_addr_data0, data);
|
||||
// Perform the write
|
||||
dm.write (dm_addr_command,
|
||||
fn_mk_command_access_reg (DM_COMMAND_ACCESS_REG_SIZE_LOWER32,
|
||||
False, // postexec
|
||||
True, // transfer
|
||||
True, // write
|
||||
regno));
|
||||
// Read status to check no error
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
while (fn_abstractcs_busy (rg_abstractcs)) seq
|
||||
$display ("Testbench: write reg: busy");
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
endseq
|
||||
$display ("Testbench: write reg => ", fshow (fn_abstractcs_cmderr (rg_abstractcs)));
|
||||
$display ("----------------\nWrite RISC-V reg");
|
||||
// Clear any prior error status
|
||||
dm.write (dm_addr_abstractcs, fn_mk_abstractcs (dm_cmderr_w1c));
|
||||
// Write data0
|
||||
dm.write (dm_addr_data0, data);
|
||||
// Perform the write
|
||||
dm.write (dm_addr_command,
|
||||
fn_mk_command_access_reg (DM_COMMAND_ACCESS_REG_SIZE_LOWER32,
|
||||
False, // postexec
|
||||
True, // transfer
|
||||
True, // write
|
||||
regno));
|
||||
// Read status to check no error
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
while (fn_abstractcs_busy (rg_abstractcs)) seq
|
||||
$display ("Testbench: write reg: busy");
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_abstractcs);
|
||||
rg_abstractcs <= x;
|
||||
endaction
|
||||
endseq
|
||||
$display ("Testbench: write reg => ", fshow (fn_abstractcs_cmderr (rg_abstractcs)));
|
||||
endseq;
|
||||
endfunction
|
||||
|
||||
@@ -188,102 +188,102 @@ module mkTestbench (Empty);
|
||||
|
||||
Stmt stmt_wait_for_sb_nonbusy = (
|
||||
seq
|
||||
rg_busy <= True;
|
||||
while (rg_busy) seq
|
||||
delay (1);
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbcs);
|
||||
let sberror = fn_sbcs_sberror (x);
|
||||
rg_busy <= (sberror == DM_SBERROR_BUSY_STALE);
|
||||
if ( (sberror != DM_SBERROR_NONE)
|
||||
&& (sberror != DM_SBERROR_BUSY_STALE))
|
||||
begin
|
||||
$display ("Testbench: stmt_wait_for_sb_nonbusy: ", fshow (sberror));
|
||||
$finish (1);
|
||||
end
|
||||
endaction
|
||||
endseq
|
||||
rg_busy <= True;
|
||||
while (rg_busy) seq
|
||||
delay (1);
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbcs);
|
||||
let sberror = fn_sbcs_sberror (x);
|
||||
rg_busy <= (sberror == DM_SBERROR_BUSY_STALE);
|
||||
if ( (sberror != DM_SBERROR_NONE)
|
||||
&& (sberror != DM_SBERROR_BUSY_STALE))
|
||||
begin
|
||||
$display ("Testbench: stmt_wait_for_sb_nonbusy: ", fshow (sberror));
|
||||
$finish (1);
|
||||
end
|
||||
endaction
|
||||
endseq
|
||||
endseq);
|
||||
|
||||
// Do a single-read from memory
|
||||
Stmt stmt_mem_read_1 = (
|
||||
seq
|
||||
dm.write (dm_addr_sbaddress0, 'h1_0000);
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (True, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
False, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbdata0);
|
||||
$display ("stmt_mem_read_1: read-data = 0x%08h", x);
|
||||
endaction
|
||||
dm.write (dm_addr_sbaddress0, 'h1_0000);
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (True, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
False, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbdata0);
|
||||
$display ("stmt_mem_read_1: read-data = 0x%08h", x);
|
||||
endaction
|
||||
endseq);
|
||||
|
||||
// Do a multiple-read from memory
|
||||
Stmt stmt_mem_read_4 = (
|
||||
seq
|
||||
dm.write (dm_addr_sbaddress0, 'h1_0000);
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (True, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
True, // sbautoincrement
|
||||
True, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
for (rg_j <= 0; rg_j < 3; rg_j <= rg_j + 1) seq
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbdata0);
|
||||
$display ("stmt_mem_read_4: read-data [%0d] = 0x%08h", rg_j, x);
|
||||
endaction
|
||||
endseq
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (False, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
False, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbdata0);
|
||||
$display ("stmt_mem_read_4: read-data [%0d] = 0x%08h", rg_j, x);
|
||||
endaction
|
||||
dm.write (dm_addr_sbaddress0, 'h1_0000);
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (True, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
True, // sbautoincrement
|
||||
True, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
for (rg_j <= 0; rg_j < 3; rg_j <= rg_j + 1) seq
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbdata0);
|
||||
$display ("stmt_mem_read_4: read-data [%0d] = 0x%08h", rg_j, x);
|
||||
endaction
|
||||
endseq
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (False, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
False, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_sbdata0);
|
||||
$display ("stmt_mem_read_4: read-data [%0d] = 0x%08h", rg_j, x);
|
||||
endaction
|
||||
endseq);
|
||||
|
||||
// Do a single-write to memory
|
||||
Stmt stmt_mem_write_1 = (
|
||||
seq
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (False, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
False, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
dm.write (dm_addr_sbaddress0, 'h1_0000);
|
||||
dm.write (dm_addr_sbdata0, 'h_BEEF);
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (False, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
False, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
dm.write (dm_addr_sbaddress0, 'h1_0000);
|
||||
dm.write (dm_addr_sbdata0, 'h_BEEF);
|
||||
endseq);
|
||||
|
||||
// Do a multiple-write to memory
|
||||
Stmt stmt_mem_write_4 = (
|
||||
seq
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (False, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
True, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
rg_addr <= 'h_2000;
|
||||
rg_data <= 'h_DAFA_0000;
|
||||
endaction
|
||||
dm.write (dm_addr_sbaddress0, rg_addr);
|
||||
for (rg_j <= 0; rg_j < 4; rg_j <= rg_j + 1) seq
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
$display ("stmt_mem_write_4: [0x%08h] x = 0x%08h", rg_addr + rg_j, rg_data);
|
||||
dm.write (dm_addr_sbdata0, rg_data);
|
||||
rg_data <= rg_data + 1;
|
||||
endaction
|
||||
endseq
|
||||
dm.write (dm_addr_sbcs, fn_mk_sbcs (False, // sbsingleread
|
||||
DM_SBACCESS_32_BIT,
|
||||
True, // sbautoincrement
|
||||
False, // sbautoread
|
||||
DM_SBERROR_UNDEF7_W1C)); // clear sberror
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
rg_addr <= 'h_2000;
|
||||
rg_data <= 'h_DAFA_0000;
|
||||
endaction
|
||||
dm.write (dm_addr_sbaddress0, rg_addr);
|
||||
for (rg_j <= 0; rg_j < 4; rg_j <= rg_j + 1) seq
|
||||
stmt_wait_for_sb_nonbusy;
|
||||
action
|
||||
$display ("stmt_mem_write_4: [0x%08h] x = 0x%08h", rg_addr + rg_j, rg_data);
|
||||
dm.write (dm_addr_sbdata0, rg_data);
|
||||
rg_data <= rg_data + 1;
|
||||
endaction
|
||||
endseq
|
||||
endseq);
|
||||
|
||||
// ================================================================
|
||||
@@ -291,173 +291,173 @@ module mkTestbench (Empty);
|
||||
|
||||
let dmcontrol_dm_reset
|
||||
= fn_mk_dmcontrol (False, // haltreq
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel
|
||||
0, // hartsel,
|
||||
False, // ndmreset
|
||||
False); // dmactive; assert reset
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel
|
||||
0, // hartsel,
|
||||
False, // ndmreset
|
||||
False); // dmactive; assert reset
|
||||
|
||||
let dmcontrol_ndmreset
|
||||
= fn_mk_dmcontrol (False, // haltreq
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
True, // ndmreset
|
||||
True); // dmactive
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
True, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
let dmcontrol_err_hasel
|
||||
= fn_mk_dmcontrol (False, // haltreq
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
True, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
True, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
let dmcontrol_err_hartsel
|
||||
= fn_mk_dmcontrol (False, // haltreq
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
3, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
3, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
let dmcontrol_hartreset
|
||||
= fn_mk_dmcontrol (False, // haltreq
|
||||
False, // resumereq
|
||||
True, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
False, // resumereq
|
||||
True, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
let dmcontrol_err_haltreq_resumereq
|
||||
= fn_mk_dmcontrol (True, // haltreq
|
||||
True, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
True, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
let dmcontrol_haltreq
|
||||
= fn_mk_dmcontrol (True, // haltreq
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
False, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
let dmcontrol_resumereq
|
||||
= fn_mk_dmcontrol (False, // haltreq
|
||||
True, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
True, // resumereq
|
||||
False, // hartreset
|
||||
False, // hasel,
|
||||
0, // hartsel
|
||||
False, // ndmreset
|
||||
True); // dmactive
|
||||
|
||||
function Stmt fn_stmt_run_control (DM_Word dm_word);
|
||||
return seq
|
||||
dm.write (dm_addr_dmcontrol, dm_word);
|
||||
delay (5);
|
||||
// Check and show status
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_dmstatus);
|
||||
$display (" ", fshow_dmstatus (x));
|
||||
endaction
|
||||
endseq;
|
||||
dm.write (dm_addr_dmcontrol, dm_word);
|
||||
delay (5);
|
||||
// Check and show status
|
||||
action
|
||||
let x <- dm.av_read (dm_addr_dmstatus);
|
||||
$display (" ", fshow_dmstatus (x));
|
||||
endaction
|
||||
endseq;
|
||||
endfunction
|
||||
|
||||
// ----------------
|
||||
// For single-step, set 'step' bit in DCSR, then run
|
||||
|
||||
let dcsr_step = {4'h4, // xdebugver
|
||||
12'b0,
|
||||
1'b0, // ebreakm
|
||||
1'b0,
|
||||
1'b0, // ebreaks
|
||||
1'b0, // ebreaku
|
||||
1'b0, // stepie
|
||||
1'b0, // stepcount
|
||||
1'b0, // steptime
|
||||
3'b0, // cause
|
||||
3'b0,
|
||||
1'b1, // step
|
||||
2'h3};
|
||||
12'b0,
|
||||
1'b0, // ebreakm
|
||||
1'b0,
|
||||
1'b0, // ebreaks
|
||||
1'b0, // ebreaku
|
||||
1'b0, // stepie
|
||||
1'b0, // stepcount
|
||||
1'b0, // steptime
|
||||
3'b0, // cause
|
||||
3'b0,
|
||||
1'b1, // step
|
||||
2'h3};
|
||||
|
||||
Stmt stmt_single_step = (
|
||||
seq
|
||||
// set 'step' in dcsr
|
||||
fn_stmt_write_reg (fromInteger (dm_command_access_reg_regno_csr_0 + csr_addr_dcsr),
|
||||
dcsr_step); // priv
|
||||
fn_stmt_run_control (dmcontrol_resumereq);
|
||||
// set 'step' in dcsr
|
||||
fn_stmt_write_reg (fromInteger (dm_command_access_reg_regno_csr_0 + csr_addr_dcsr),
|
||||
dcsr_step); // priv
|
||||
fn_stmt_run_control (dmcontrol_resumereq);
|
||||
endseq);
|
||||
|
||||
// ================================================================
|
||||
// Top-level test. Comment/Uncomment desired parts.
|
||||
|
||||
Stmt test = seq
|
||||
// Reset DM
|
||||
$display ("----------------\n'Testbench: Reset DM'");
|
||||
fn_stmt_run_control (dmcontrol_dm_reset);
|
||||
// Reset DM
|
||||
$display ("----------------\n'Testbench: Reset DM'");
|
||||
fn_stmt_run_control (dmcontrol_dm_reset);
|
||||
|
||||
/*
|
||||
$display ("----------------\n'Testbench: Reset Platform'");
|
||||
fn_stmt_run_control (dmcontrol_ndmreset);
|
||||
/*
|
||||
$display ("----------------\n'Testbench: Reset Platform'");
|
||||
fn_stmt_run_control (dmcontrol_ndmreset);
|
||||
|
||||
$display ("----------------\n'Testbench: Err hasel'");
|
||||
fn_stmt_run_control (dmcontrol_err_hasel);
|
||||
$display ("----------------\n'Testbench: Err hasel'");
|
||||
fn_stmt_run_control (dmcontrol_err_hasel);
|
||||
|
||||
$display ("----------------\n'Testbench: Err hartsel'");
|
||||
fn_stmt_run_control (dmcontrol_err_hartsel);
|
||||
$display ("----------------\n'Testbench: Err hartsel'");
|
||||
fn_stmt_run_control (dmcontrol_err_hartsel);
|
||||
|
||||
$display ("----------------\n'Testbench: Reset hart'");
|
||||
fn_stmt_run_control (dmcontrol_hartreset);
|
||||
$display ("----------------\n'Testbench: Reset hart'");
|
||||
fn_stmt_run_control (dmcontrol_hartreset);
|
||||
|
||||
$display ("----------------\n'Testbench: Err haltreq and resumereq'");
|
||||
fn_stmt_run_control (dmcontrol_err_haltreq_resumereq);
|
||||
$display ("----------------\n'Testbench: Err haltreq and resumereq'");
|
||||
fn_stmt_run_control (dmcontrol_err_haltreq_resumereq);
|
||||
|
||||
$display ("----------------\n'Testbench: Continue'");
|
||||
fn_stmt_run_control (dmcontrol_resumereq);
|
||||
$display ("----------------\n'Testbench: Continue'");
|
||||
fn_stmt_run_control (dmcontrol_resumereq);
|
||||
|
||||
$display ("----------------\n'Testbench: Halt'");
|
||||
fn_stmt_run_control (dmcontrol_haltreq);
|
||||
$display ("----------------\n'Testbench: Halt'");
|
||||
fn_stmt_run_control (dmcontrol_haltreq);
|
||||
|
||||
$display ("----------------\n'Testbench: Single step'");
|
||||
stmt_single_step;
|
||||
*/
|
||||
$display ("----------------\n'Testbench: Single step'");
|
||||
stmt_single_step;
|
||||
*/
|
||||
|
||||
$display ("----------------\n'Testbench: Read GPR'");
|
||||
fn_stmt_read_reg (fromInteger (dm_command_access_reg_regno_gpr_0 + 5));
|
||||
$display ("----------------\n'Testbench: Read CSR'");
|
||||
fn_stmt_read_reg (fromInteger (dm_command_access_reg_regno_csr_0 + 3));
|
||||
$display ("----------------\n'Testbench: Read GPR'");
|
||||
fn_stmt_read_reg (fromInteger (dm_command_access_reg_regno_gpr_0 + 5));
|
||||
$display ("----------------\n'Testbench: Read CSR'");
|
||||
fn_stmt_read_reg (fromInteger (dm_command_access_reg_regno_csr_0 + 3));
|
||||
|
||||
$display ("----------------\n'Testbench: Write GPR'");
|
||||
fn_stmt_write_reg (fromInteger (dm_command_access_reg_regno_gpr_0 + 5), 'h_AAAA_0005);
|
||||
$display ("----------------\n'Testbench: Write CSR'");
|
||||
fn_stmt_write_reg (fromInteger (dm_command_access_reg_regno_csr_0 + 3), 'h_CCCC_0003);
|
||||
$display ("----------------\n'Testbench: Write GPR'");
|
||||
fn_stmt_write_reg (fromInteger (dm_command_access_reg_regno_gpr_0 + 5), 'h_AAAA_0005);
|
||||
$display ("----------------\n'Testbench: Write CSR'");
|
||||
fn_stmt_write_reg (fromInteger (dm_command_access_reg_regno_csr_0 + 3), 'h_CCCC_0003);
|
||||
|
||||
/*
|
||||
$display ("----------------\n'Testbench: Read 1'");
|
||||
stmt_mem_read_1;
|
||||
/*
|
||||
$display ("----------------\n'Testbench: Read 1'");
|
||||
stmt_mem_read_1;
|
||||
|
||||
$display ("----------------\n'Testbench: Write 1'");
|
||||
stmt_mem_write_1;
|
||||
$display ("----------------\n'Testbench: Write 1'");
|
||||
stmt_mem_write_1;
|
||||
|
||||
$display ("----------------\n'Testbench: Read 4'");
|
||||
stmt_mem_read_4;
|
||||
$display ("----------------\n'Testbench: Read 4'");
|
||||
stmt_mem_read_4;
|
||||
|
||||
$display ("----------------\n'Testbench: Write 4'");
|
||||
stmt_mem_write_4;
|
||||
*/
|
||||
$display ("----------------\n'Testbench: Write 4'");
|
||||
stmt_mem_write_4;
|
||||
*/
|
||||
|
||||
await (False);
|
||||
endseq;
|
||||
await (False);
|
||||
endseq;
|
||||
|
||||
mkAutoFSM (test);
|
||||
|
||||
@@ -518,9 +518,9 @@ module mkHart_Model #(parameter Bit #(10) hart_id) (Hart_DM_IFC);
|
||||
rg_hart_running <= True;
|
||||
|
||||
if (rg_hart_running)
|
||||
$display ("Testbench.hart [%0d].rl_resume_hart: already running", hart_id);
|
||||
$display ("Testbench.hart [%0d].rl_resume_hart: already running", hart_id);
|
||||
else
|
||||
$display ("Testbench.hart [%0d].rl_resume_hart: resuming", hart_id);
|
||||
$display ("Testbench.hart [%0d].rl_resume_hart: resuming", hart_id);
|
||||
|
||||
f_hart_run_rsps.enq (True);
|
||||
endrule
|
||||
@@ -530,9 +530,9 @@ module mkHart_Model #(parameter Bit #(10) hart_id) (Hart_DM_IFC);
|
||||
rg_hart_running <= False;
|
||||
|
||||
if (rg_hart_running)
|
||||
$display ("Testbench.hart [%0d].rl_halt_hart: halting", hart_id);
|
||||
$display ("Testbench.hart [%0d].rl_halt_hart: halting", hart_id);
|
||||
else
|
||||
$display ("Testbench.hart [%0d].rl_halt_hart: already halted", hart_id);
|
||||
$display ("Testbench.hart [%0d].rl_halt_hart: already halted", hart_id);
|
||||
|
||||
f_hart_run_rsps.enq (False);
|
||||
endrule
|
||||
@@ -544,8 +544,8 @@ module mkHart_Model #(parameter Bit #(10) hart_id) (Hart_DM_IFC);
|
||||
let rda <- pop_o (trx_buf_gprs.master.fo_rda);
|
||||
Bit #(32) data = extend (rda.addr) + 'h1000;
|
||||
let rdr = TRX_RdR {trans_id: rda.trans_id,
|
||||
status: TRX_OKAY,
|
||||
data: data};
|
||||
status: TRX_OKAY,
|
||||
data: data};
|
||||
trx_buf_gprs.master.fi_rdr.enq (rdr);
|
||||
$display ("Testbench.hart [%0d]: Read GPR [%0h] => 0x%08h", hart_id, rda.addr, data);
|
||||
endrule
|
||||
@@ -554,8 +554,8 @@ module mkHart_Model #(parameter Bit #(10) hart_id) (Hart_DM_IFC);
|
||||
let rda <- pop_o (trx_buf_csrs.master.fo_rda);
|
||||
Bit #(32) data = extend (rda.addr) + 'h2000;
|
||||
let rdr = TRX_RdR {trans_id: rda.trans_id,
|
||||
status: TRX_OKAY,
|
||||
data: data};
|
||||
status: TRX_OKAY,
|
||||
data: data};
|
||||
trx_buf_csrs.master.fi_rdr.enq (rdr);
|
||||
$display ("Testbench.hart [%0d]: Read CSR [%0h] => 0x%08h", hart_id, rda.addr, data);
|
||||
endrule
|
||||
|
||||
@@ -234,28 +234,28 @@ deriving (FShow, Bits);
|
||||
function Decoded_Instr fv_decode (Instr instr);
|
||||
return Decoded_Instr {opcode: instr_opcode (instr),
|
||||
|
||||
rd: instr_rd (instr),
|
||||
rs1: instr_rs1 (instr),
|
||||
rs2: instr_rs2 (instr),
|
||||
rs3: instr_rs3 (instr),
|
||||
csr: instr_csr (instr),
|
||||
rd: instr_rd (instr),
|
||||
rs1: instr_rs1 (instr),
|
||||
rs2: instr_rs2 (instr),
|
||||
rs3: instr_rs3 (instr),
|
||||
csr: instr_csr (instr),
|
||||
|
||||
funct3: instr_funct3 (instr),
|
||||
funct5: instr_funct5 (instr),
|
||||
funct7: instr_funct7 (instr),
|
||||
funct10: instr_funct10 (instr),
|
||||
funct3: instr_funct3 (instr),
|
||||
funct5: instr_funct5 (instr),
|
||||
funct7: instr_funct7 (instr),
|
||||
funct10: instr_funct10 (instr),
|
||||
|
||||
imm12_I: instr_I_imm12 (instr),
|
||||
imm12_S: instr_S_imm12 (instr),
|
||||
imm13_SB: instr_SB_imm13 (instr),
|
||||
imm20_U: instr_U_imm20 (instr),
|
||||
imm21_UJ: instr_UJ_imm21 (instr),
|
||||
imm12_I: instr_I_imm12 (instr),
|
||||
imm12_S: instr_S_imm12 (instr),
|
||||
imm13_SB: instr_SB_imm13 (instr),
|
||||
imm20_U: instr_U_imm20 (instr),
|
||||
imm21_UJ: instr_UJ_imm21 (instr),
|
||||
|
||||
pred: instr_pred (instr),
|
||||
succ: instr_succ (instr),
|
||||
pred: instr_pred (instr),
|
||||
succ: instr_succ (instr),
|
||||
|
||||
aqrl: instr_aqrl (instr)
|
||||
};
|
||||
aqrl: instr_aqrl (instr)
|
||||
};
|
||||
endfunction
|
||||
|
||||
// Decodes if we need to read the GPR register file. This step becomes necessary
|
||||
@@ -269,7 +269,7 @@ endfunction
|
||||
// if (di.opcode != op_FP) begin
|
||||
// return (tuple2 (False, True)); // Regular op with GPR read
|
||||
// end
|
||||
//
|
||||
//
|
||||
// // This is an FP operation. The following f5 values would work for F and
|
||||
// // D subsets
|
||||
// else begin
|
||||
@@ -379,9 +379,9 @@ deriving (Eq, Bits, FShow);
|
||||
// Data sizes for LOAD/STORE
|
||||
|
||||
typedef enum {BITS8,
|
||||
BITS16,
|
||||
BITS32,
|
||||
BITS64 // Even in RV32, to allow for Double (floating point)
|
||||
BITS16,
|
||||
BITS32,
|
||||
BITS64 // Even in RV32, to allow for Double (floating point)
|
||||
} Mem_Data_Size
|
||||
deriving (Eq, Bits, FShow);
|
||||
|
||||
@@ -443,23 +443,23 @@ deriving (FShow);
|
||||
instance Bits #(Fence_Ordering, 8);
|
||||
function Bit #(8) pack (Fence_Ordering fo);
|
||||
return {pack (fo.pi),
|
||||
pack (fo.po),
|
||||
pack (fo.pr),
|
||||
pack (fo.pw),
|
||||
pack (fo.si),
|
||||
pack (fo.so),
|
||||
pack (fo.sr),
|
||||
pack (fo.sw) };
|
||||
pack (fo.po),
|
||||
pack (fo.pr),
|
||||
pack (fo.pw),
|
||||
pack (fo.si),
|
||||
pack (fo.so),
|
||||
pack (fo.sr),
|
||||
pack (fo.sw) };
|
||||
endfunction
|
||||
function Fence_Ordering unpack (Bit #(8) b8);
|
||||
return Fence_Ordering {pi: unpack (b8 [7]),
|
||||
po: unpack (b8 [6]),
|
||||
pr: unpack (b8 [5]),
|
||||
pw: unpack (b8 [4]),
|
||||
si: unpack (b8 [3]),
|
||||
so: unpack (b8 [2]),
|
||||
sr: unpack (b8 [1]),
|
||||
sw: unpack (b8 [0]) };
|
||||
po: unpack (b8 [6]),
|
||||
pr: unpack (b8 [5]),
|
||||
pw: unpack (b8 [4]),
|
||||
si: unpack (b8 [3]),
|
||||
so: unpack (b8 [2]),
|
||||
sr: unpack (b8 [1]),
|
||||
sw: unpack (b8 [0]) };
|
||||
endfunction
|
||||
endinstance
|
||||
|
||||
@@ -613,10 +613,10 @@ Bit #(10) f10_REMUW = 10'b000_0001_111;
|
||||
|
||||
function Bool is_OP_32_MUL_DIV_REM (Bit #(10) f10);
|
||||
return ( (f10 == f10_MULW)
|
||||
|| (f10 == f10_DIVW)
|
||||
|| (f10 == f10_DIVUW)
|
||||
|| (f10 == f10_REMW)
|
||||
|| (f10 == f10_REMUW));
|
||||
|| (f10 == f10_DIVW)
|
||||
|| (f10 == f10_DIVUW)
|
||||
|| (f10 == f10_REMW)
|
||||
|| (f10 == f10_REMUW));
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -802,15 +802,15 @@ endfunction
|
||||
|
||||
// Check if a rounding mode value in the FCSR.FRM is valid
|
||||
function Bool fv_fcsr_frm_valid (Bit #(3) frm);
|
||||
return ( (frm != 3'b101)
|
||||
return ( (frm != 3'b101)
|
||||
&& (frm != 3'b110)
|
||||
&& (frm != 3'b111)
|
||||
);
|
||||
endfunction
|
||||
endfunction
|
||||
|
||||
// Check if a rounding mode value in the instr is valid
|
||||
function Bool fv_inst_frm_valid (Bit #(3) frm);
|
||||
return ( (frm != 3'b101)
|
||||
return ( (frm != 3'b101)
|
||||
&& (frm != 3'b110)
|
||||
);
|
||||
endfunction
|
||||
@@ -841,12 +841,12 @@ function Bool fv_is_fp_instr_legal (
|
||||
return (f2 == f2_S); // Only SP is legal
|
||||
`endif
|
||||
else
|
||||
if ( (f7 == f7_FADD_S)
|
||||
|| (f7 == f7_FSUB_S)
|
||||
|| (f7 == f7_FMUL_S)
|
||||
if ( (f7 == f7_FADD_S)
|
||||
|| (f7 == f7_FSUB_S)
|
||||
|| (f7 == f7_FMUL_S)
|
||||
`ifdef ISA_FD_DIV
|
||||
|| (f7 == f7_FDIV_S)
|
||||
|| (f7 == f7_FSQRT_S)
|
||||
|| (f7 == f7_FDIV_S)
|
||||
|| (f7 == f7_FSQRT_S)
|
||||
`endif
|
||||
|| ((f7 == f7_FSGNJ_S) && ( rm == 0))
|
||||
|| ((f7 == f7_FSGNJ_S) && ( rm == 1))
|
||||
@@ -856,10 +856,10 @@ function Bool fv_is_fp_instr_legal (
|
||||
`ifdef RV64
|
||||
|| ((f7 == f7_FCVT_L_S) && (rs2 == 2))
|
||||
|| ((f7 == f7_FCVT_LU_S)&& (rs2 == 3))
|
||||
`endif
|
||||
`endif
|
||||
|| ((f7 == f7_FCVT_S_W) && (rs2 == 0))
|
||||
|| ((f7 == f7_FCVT_S_WU)&& (rs2 == 1))
|
||||
`ifdef RV64
|
||||
|| ((f7 == f7_FCVT_S_WU)&& (rs2 == 1))
|
||||
`ifdef RV64
|
||||
|| ((f7 == f7_FCVT_S_L) && (rs2 == 2))
|
||||
|| ((f7 == f7_FCVT_S_LU)&& (rs2 == 3))
|
||||
`endif
|
||||
@@ -872,12 +872,12 @@ function Bool fv_is_fp_instr_legal (
|
||||
|| ((f7 == f7_FMV_W_X) && ( rm == 0))
|
||||
|| ((f7 == f7_FCLASS_S) && ( rm == 1))
|
||||
`ifdef ISA_D
|
||||
|| (f7 == f7_FADD_D)
|
||||
|| (f7 == f7_FSUB_D)
|
||||
|| (f7 == f7_FMUL_D)
|
||||
|| (f7 == f7_FADD_D)
|
||||
|| (f7 == f7_FSUB_D)
|
||||
|| (f7 == f7_FMUL_D)
|
||||
`ifdef ISA_FD_DIV
|
||||
|| (f7 == f7_FDIV_D)
|
||||
|| (f7 == f7_FSQRT_D)
|
||||
|| (f7 == f7_FDIV_D)
|
||||
|| (f7 == f7_FSQRT_D)
|
||||
`endif
|
||||
|| ((f7 == f7_FSGNJ_D) && ( rm == 0))
|
||||
|| ((f7 == f7_FSGNJ_D) && ( rm == 1))
|
||||
@@ -887,10 +887,10 @@ function Bool fv_is_fp_instr_legal (
|
||||
`ifdef RV64
|
||||
|| ((f7 == f7_FCVT_L_D) && (rs2 == 2))
|
||||
|| ((f7 == f7_FCVT_LU_D)&& (rs2 == 3))
|
||||
`endif
|
||||
`endif
|
||||
|| ((f7 == f7_FCVT_D_W) && (rs2 == 0))
|
||||
|| ((f7 == f7_FCVT_D_WU)&& (rs2 == 1))
|
||||
`ifdef RV64
|
||||
|| ((f7 == f7_FCVT_D_WU)&& (rs2 == 1))
|
||||
`ifdef RV64
|
||||
|| ((f7 == f7_FCVT_D_L) && (rs2 == 2))
|
||||
|| ((f7 == f7_FCVT_D_LU)&& (rs2 == 3))
|
||||
`endif
|
||||
@@ -984,7 +984,7 @@ endfunction
|
||||
|
||||
function Bool f3_is_CSRR_S_or_C (Bit #(3) f3);
|
||||
return ((f3 == f3_CSRRS) || (f3 == f3_CSRRSI) ||
|
||||
(f3 == f3_CSRRC) || (f3 == f3_CSRRCI));
|
||||
(f3 == f3_CSRRC) || (f3 == f3_CSRRCI));
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -1001,11 +1001,11 @@ Priv_Mode m_Priv_Mode = 2'b11;
|
||||
|
||||
function Fmt fshow_Priv_Mode (Priv_Mode pm);
|
||||
return case (pm)
|
||||
u_Priv_Mode: $format ("U");
|
||||
s_Priv_Mode: $format ("S");
|
||||
m_Priv_Mode: $format ("M");
|
||||
default: $format ("RESERVED");
|
||||
endcase;
|
||||
u_Priv_Mode: $format ("U");
|
||||
s_Priv_Mode: $format ("S");
|
||||
m_Priv_Mode: $format ("M");
|
||||
default: $format ("RESERVED");
|
||||
endcase;
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -1106,7 +1106,7 @@ CSR_Addr csr_addr_hpmcounter29h = 12'hC9D; // Upper 32 bits of performance
|
||||
CSR_Addr csr_addr_hpmcounter30h = 12'hC9E; // Upper 32 bits of performance-monitoring counter
|
||||
CSR_Addr csr_addr_hpmcounter31h = 12'hC9F; // Upper 32 bits of performance-monitoring counter
|
||||
|
||||
// Information from the CSR on a new trap.
|
||||
// Information from the CSR on a new trap.
|
||||
typedef struct {
|
||||
Addr pc;
|
||||
WordXL mstatus;
|
||||
|
||||
@@ -201,56 +201,56 @@ Bit #(2) misa_mxl_128 = 3;
|
||||
|
||||
function WordXL misa_to_word (MISA ms);
|
||||
return {ms.mxl,
|
||||
0, // expands appropriately for RV32 and RV64
|
||||
ms.z, ms.y,
|
||||
ms.x, ms.w, ms.v, ms.u, ms.t, ms.s, ms.r, ms.q,
|
||||
ms.p, ms.o, ms.n, ms.m, ms.l, ms.k, ms.j, ms.i,
|
||||
ms.h, ms.g, ms.f, ms.e, ms.d, ms.c, ms.b, ms.a};
|
||||
0, // expands appropriately for RV32 and RV64
|
||||
ms.z, ms.y,
|
||||
ms.x, ms.w, ms.v, ms.u, ms.t, ms.s, ms.r, ms.q,
|
||||
ms.p, ms.o, ms.n, ms.m, ms.l, ms.k, ms.j, ms.i,
|
||||
ms.h, ms.g, ms.f, ms.e, ms.d, ms.c, ms.b, ms.a};
|
||||
endfunction
|
||||
|
||||
function MISA word_to_misa (WordXL x);
|
||||
return MISA {mxl: x [xlen-1:xlen-2],
|
||||
z: x [25], y: x [24],
|
||||
x: x [23], w: x [22], v: x [21], u: x [20], t: x [19], s: x [18], r: x [17], q: x [16],
|
||||
p: x [15], o: x [14], n: x [13], m: x [12], l: x [11], k: x [10], j: x [9], i: x [8],
|
||||
h: x [7], g: x [6], f: x [5], e: x [4], d: x [3], c: x [2], b: x [1], a: x [0]};
|
||||
z: x [25], y: x [24],
|
||||
x: x [23], w: x [22], v: x [21], u: x [20], t: x [19], s: x [18], r: x [17], q: x [16],
|
||||
p: x [15], o: x [14], n: x [13], m: x [12], l: x [11], k: x [10], j: x [9], i: x [8],
|
||||
h: x [7], g: x [6], f: x [5], e: x [4], d: x [3], c: x [2], b: x [1], a: x [0]};
|
||||
endfunction
|
||||
|
||||
instance FShow #(MISA);
|
||||
function Fmt fshow (MISA misa);
|
||||
let fmt_mxl = case (misa.mxl)
|
||||
1: $format ("mxl 32");
|
||||
2: $format ("mxl 64");
|
||||
3: $format ("mxl 128");
|
||||
default: $format ("mxl unknown %0d", misa.mxl);
|
||||
endcase;
|
||||
1: $format ("mxl 32");
|
||||
2: $format ("mxl 64");
|
||||
3: $format ("mxl 128");
|
||||
default: $format ("mxl unknown %0d", misa.mxl);
|
||||
endcase;
|
||||
return ( fmt_mxl
|
||||
+ $format ((misa.z == 1'b1) ? "Z" : "")
|
||||
+ $format ((misa.y == 1'b1) ? "Y" : "")
|
||||
+ $format ((misa.x == 1'b1) ? "X" : "")
|
||||
+ $format ((misa.w == 1'b1) ? "W" : "")
|
||||
+ $format ((misa.v == 1'b1) ? "V" : "")
|
||||
+ $format ((misa.u == 1'b1) ? "U" : "")
|
||||
+ $format ((misa.t == 1'b1) ? "T" : "")
|
||||
+ $format ((misa.s == 1'b1) ? "S" : "")
|
||||
+ $format ((misa.r == 1'b1) ? "R" : "")
|
||||
+ $format ((misa.q == 1'b1) ? "Q" : "")
|
||||
+ $format ((misa.p == 1'b1) ? "P" : "")
|
||||
+ $format ((misa.o == 1'b1) ? "O" : "")
|
||||
+ $format ((misa.n == 1'b1) ? "N" : "")
|
||||
+ $format ((misa.m == 1'b1) ? "M" : "")
|
||||
+ $format ((misa.l == 1'b1) ? "L" : "")
|
||||
+ $format ((misa.k == 1'b1) ? "K" : "")
|
||||
+ $format ((misa.j == 1'b1) ? "J" : "")
|
||||
+ $format ((misa.i == 1'b1) ? "I" : "")
|
||||
+ $format ((misa.h == 1'b1) ? "H" : "")
|
||||
+ $format ((misa.g == 1'b1) ? "G" : "")
|
||||
+ $format ((misa.f == 1'b1) ? "F" : "")
|
||||
+ $format ((misa.d == 1'b1) ? "E" : "")
|
||||
+ $format ((misa.d == 1'b1) ? "D" : "")
|
||||
+ $format ((misa.c == 1'b1) ? "C" : "")
|
||||
+ $format ((misa.b == 1'b1) ? "B" : "")
|
||||
+ $format ((misa.a == 1'b1) ? "A" : ""));
|
||||
+ $format ((misa.z == 1'b1) ? "Z" : "")
|
||||
+ $format ((misa.y == 1'b1) ? "Y" : "")
|
||||
+ $format ((misa.x == 1'b1) ? "X" : "")
|
||||
+ $format ((misa.w == 1'b1) ? "W" : "")
|
||||
+ $format ((misa.v == 1'b1) ? "V" : "")
|
||||
+ $format ((misa.u == 1'b1) ? "U" : "")
|
||||
+ $format ((misa.t == 1'b1) ? "T" : "")
|
||||
+ $format ((misa.s == 1'b1) ? "S" : "")
|
||||
+ $format ((misa.r == 1'b1) ? "R" : "")
|
||||
+ $format ((misa.q == 1'b1) ? "Q" : "")
|
||||
+ $format ((misa.p == 1'b1) ? "P" : "")
|
||||
+ $format ((misa.o == 1'b1) ? "O" : "")
|
||||
+ $format ((misa.n == 1'b1) ? "N" : "")
|
||||
+ $format ((misa.m == 1'b1) ? "M" : "")
|
||||
+ $format ((misa.l == 1'b1) ? "L" : "")
|
||||
+ $format ((misa.k == 1'b1) ? "K" : "")
|
||||
+ $format ((misa.j == 1'b1) ? "J" : "")
|
||||
+ $format ((misa.i == 1'b1) ? "I" : "")
|
||||
+ $format ((misa.h == 1'b1) ? "H" : "")
|
||||
+ $format ((misa.g == 1'b1) ? "G" : "")
|
||||
+ $format ((misa.f == 1'b1) ? "F" : "")
|
||||
+ $format ((misa.d == 1'b1) ? "E" : "")
|
||||
+ $format ((misa.d == 1'b1) ? "D" : "")
|
||||
+ $format ((misa.c == 1'b1) ? "C" : "")
|
||||
+ $format ((misa.b == 1'b1) ? "B" : "")
|
||||
+ $format ((misa.a == 1'b1) ? "A" : ""));
|
||||
endfunction
|
||||
endinstance
|
||||
|
||||
@@ -314,43 +314,43 @@ function Fmt fshow_mstatus (MISA misa, WordXL mstatus);
|
||||
Bit #(2) mpp = fv_get_bits (mstatus, fromInteger (mstatus_mpp_bitpos));
|
||||
|
||||
return ( $format ("MStatus{")
|
||||
+ $format ("sd:%0d", fv_mstatus_sd (mstatus))
|
||||
+ $format ("sd:%0d", fv_mstatus_sd (mstatus))
|
||||
|
||||
+ ((misa.mxl == misa_mxl_64) ? $format (" sxl:%0d uxl:%0d", sxl, uxl) : $format (""))
|
||||
+ ((misa.mxl == misa_mxl_64) ? $format (" sxl:%0d uxl:%0d", sxl, uxl) : $format (""))
|
||||
|
||||
+ $format (" tsr:%0d", mstatus [mstatus_tsr_bitpos])
|
||||
+ $format (" tw:%0d", mstatus [mstatus_tw_bitpos])
|
||||
+ $format (" tvm:%0d", mstatus [mstatus_tvm_bitpos])
|
||||
+ $format (" mxr:%0d", mstatus [mstatus_mxr_bitpos])
|
||||
+ $format (" sum:%0d", mstatus [mstatus_sum_bitpos])
|
||||
+ $format (" mprv:%0d", mstatus [mstatus_mprv_bitpos])
|
||||
+ $format (" tsr:%0d", mstatus [mstatus_tsr_bitpos])
|
||||
+ $format (" tw:%0d", mstatus [mstatus_tw_bitpos])
|
||||
+ $format (" tvm:%0d", mstatus [mstatus_tvm_bitpos])
|
||||
+ $format (" mxr:%0d", mstatus [mstatus_mxr_bitpos])
|
||||
+ $format (" sum:%0d", mstatus [mstatus_sum_bitpos])
|
||||
+ $format (" mprv:%0d", mstatus [mstatus_mprv_bitpos])
|
||||
|
||||
+ $format (" xs:%0d", xs)
|
||||
+ $format (" fs:%0d", fs)
|
||||
+ $format (" xs:%0d", xs)
|
||||
+ $format (" fs:%0d", fs)
|
||||
|
||||
+ $format (" mpp:%0d", mpp)
|
||||
+ $format (" spp:%0d", mstatus [mstatus_spp_bitpos])
|
||||
+ $format (" mpp:%0d", mpp)
|
||||
+ $format (" spp:%0d", mstatus [mstatus_spp_bitpos])
|
||||
|
||||
+ $format (" pies:%0d_%0d%0d",
|
||||
mstatus [mstatus_mpie_bitpos], mstatus [mstatus_spie_bitpos], mstatus [mstatus_upie_bitpos])
|
||||
+ $format (" pies:%0d_%0d%0d",
|
||||
mstatus [mstatus_mpie_bitpos], mstatus [mstatus_spie_bitpos], mstatus [mstatus_upie_bitpos])
|
||||
|
||||
+ $format (" ies:%0d_%0d%0d",
|
||||
mstatus [mstatus_mie_bitpos], mstatus [mstatus_sie_bitpos], mstatus [mstatus_uie_bitpos])
|
||||
+ $format ("}")
|
||||
);
|
||||
+ $format (" ies:%0d_%0d%0d",
|
||||
mstatus [mstatus_mie_bitpos], mstatus [mstatus_sie_bitpos], mstatus [mstatus_uie_bitpos])
|
||||
+ $format ("}")
|
||||
);
|
||||
endfunction
|
||||
|
||||
// ----------------
|
||||
// Help functions to manipulate mstatus on traps and trap-returns
|
||||
|
||||
function Priv_Mode fv_new_priv_on_exception (MISA misa,
|
||||
Priv_Mode from_priv,
|
||||
Bool interrupt,
|
||||
Exc_Code exc_code,
|
||||
Bit #(16) medeleg,
|
||||
Bit #(12) mideleg,
|
||||
Bit #(16) sedeleg,
|
||||
Bit #(12) sideleg);
|
||||
Priv_Mode from_priv,
|
||||
Bool interrupt,
|
||||
Exc_Code exc_code,
|
||||
Bit #(16) medeleg,
|
||||
Bit #(12) mideleg,
|
||||
Bit #(16) sedeleg,
|
||||
Bit #(12) sideleg);
|
||||
Priv_Mode to_priv = m_Priv_Mode;
|
||||
Bit #(1) deleg_bit = 1'b0;
|
||||
|
||||
@@ -358,39 +358,39 @@ function Priv_Mode fv_new_priv_on_exception (MISA misa,
|
||||
if (from_priv < m_Priv_Mode) begin
|
||||
// If S is supported
|
||||
if (misa.s == 1'b1) begin
|
||||
// Look in medeleg/mideleg for the cause bit; if set, delegate.
|
||||
if (interrupt)
|
||||
deleg_bit = mideleg [exc_code];
|
||||
else
|
||||
deleg_bit = medeleg [exc_code];
|
||||
if (deleg_bit == 1'b1) begin
|
||||
// If the current priv mode is S, then delegate to S.
|
||||
to_priv = s_Priv_Mode;
|
||||
// If the current priv mode is U, and user mode traps are supported,
|
||||
// then consult sedeleg/sideleg to determine if delegated to U mode.
|
||||
if ((from_priv == u_Priv_Mode) && (misa.n == 1'b1)) begin
|
||||
if (interrupt)
|
||||
deleg_bit = sideleg [exc_code];
|
||||
else
|
||||
deleg_bit = sedeleg [exc_code];
|
||||
if (deleg_bit == 1'b1)
|
||||
to_priv = u_Priv_Mode;
|
||||
end
|
||||
end
|
||||
// Look in medeleg/mideleg for the cause bit; if set, delegate.
|
||||
if (interrupt)
|
||||
deleg_bit = mideleg [exc_code];
|
||||
else
|
||||
deleg_bit = medeleg [exc_code];
|
||||
if (deleg_bit == 1'b1) begin
|
||||
// If the current priv mode is S, then delegate to S.
|
||||
to_priv = s_Priv_Mode;
|
||||
// If the current priv mode is U, and user mode traps are supported,
|
||||
// then consult sedeleg/sideleg to determine if delegated to U mode.
|
||||
if ((from_priv == u_Priv_Mode) && (misa.n == 1'b1)) begin
|
||||
if (interrupt)
|
||||
deleg_bit = sideleg [exc_code];
|
||||
else
|
||||
deleg_bit = sedeleg [exc_code];
|
||||
if (deleg_bit == 1'b1)
|
||||
to_priv = u_Priv_Mode;
|
||||
end
|
||||
end
|
||||
end
|
||||
else begin
|
||||
// S is not supported
|
||||
// If user mode traps are supported,
|
||||
// then consult medele/mideleg to determine if delegated to U mode.
|
||||
if (misa.n == 1'b1) begin
|
||||
// Look in medeleg/mideleg for the cause bit; if set, delegate.
|
||||
if (interrupt)
|
||||
deleg_bit = mideleg [exc_code];
|
||||
else
|
||||
deleg_bit = medeleg [exc_code];
|
||||
if (deleg_bit == 1'b1)
|
||||
to_priv = u_Priv_Mode;
|
||||
end
|
||||
// S is not supported
|
||||
// If user mode traps are supported,
|
||||
// then consult medele/mideleg to determine if delegated to U mode.
|
||||
if (misa.n == 1'b1) begin
|
||||
// Look in medeleg/mideleg for the cause bit; if set, delegate.
|
||||
if (interrupt)
|
||||
deleg_bit = mideleg [exc_code];
|
||||
else
|
||||
deleg_bit = medeleg [exc_code];
|
||||
if (deleg_bit == 1'b1)
|
||||
to_priv = u_Priv_Mode;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -407,14 +407,14 @@ function WordXL fv_new_mstatus_on_exception (WordXL mstatus, Priv_Mode from_y, P
|
||||
|
||||
// xPP = y Assert: (to_x == m_Priv_Mode) || (to_x == s_Priv_Mode)
|
||||
mstatus = ( (to_x == m_Priv_Mode)
|
||||
? fv_assign_bits (mstatus, fromInteger (mstatus_mpp_bitpos), from_y)
|
||||
: fv_assign_bit (mstatus, fromInteger (mstatus_spp_bitpos), from_y [0]));
|
||||
? fv_assign_bits (mstatus, fromInteger (mstatus_mpp_bitpos), from_y)
|
||||
: fv_assign_bit (mstatus, fromInteger (mstatus_spp_bitpos), from_y [0]));
|
||||
return mstatus;
|
||||
endfunction
|
||||
|
||||
function Tuple2 #(WordXL, Priv_Mode) fv_new_mstatus_on_ret (MISA misa,
|
||||
WordXL mstatus,
|
||||
Priv_Mode from_x);
|
||||
WordXL mstatus,
|
||||
Priv_Mode from_x);
|
||||
Bit #(6) ie_from_x = extend (from_x);
|
||||
Bit #(6) pie_from_x = fromInteger (mstatus_upie_bitpos) + extend (from_x);
|
||||
|
||||
@@ -478,20 +478,20 @@ deriving (Bits, FShow);
|
||||
function WordXL mcounteren_to_word (MCounteren mc);
|
||||
return {0,
|
||||
mc.ir,
|
||||
mc.tm,
|
||||
mc.cy};
|
||||
mc.tm,
|
||||
mc.cy};
|
||||
endfunction
|
||||
|
||||
function MCounteren word_to_mcounteren (WordXL x);
|
||||
return MCounteren {ir: x[2],
|
||||
tm: x[1],
|
||||
cy: x[0]};
|
||||
cy: x[0]};
|
||||
endfunction
|
||||
|
||||
function MCounteren mcounteren_reset_value;
|
||||
return MCounteren {ir: 1'b0,
|
||||
tm: 1'b0,
|
||||
cy: 1'b0};
|
||||
cy: 1'b0};
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -521,9 +521,9 @@ deriving (Bits);
|
||||
instance FShow #(MCause);
|
||||
function Fmt fshow (MCause mc);
|
||||
if (mc.interrupt == 1)
|
||||
return fshow_interrupt_Exc_Code (mc.exc_code);
|
||||
return fshow_interrupt_Exc_Code (mc.exc_code);
|
||||
else
|
||||
return fshow_trap_Exc_Code (mc.exc_code);
|
||||
return fshow_trap_Exc_Code (mc.exc_code);
|
||||
endfunction
|
||||
endinstance
|
||||
|
||||
@@ -533,7 +533,7 @@ endfunction
|
||||
|
||||
function MCause word_to_mcause (WordXL x);
|
||||
return MCause {interrupt: msb (x),
|
||||
exc_code: truncate (x)};
|
||||
exc_code: truncate (x)};
|
||||
endfunction
|
||||
|
||||
// Exception Codes in mcause
|
||||
@@ -583,47 +583,47 @@ Exc_Code exc_code_STORE_AMO_PAGE_FAULT = 15;
|
||||
|
||||
function Fmt fshow_interrupt_Exc_Code (Exc_Code exc_code);
|
||||
return case (exc_code)
|
||||
exc_code_USER_SW_INTERRUPT: $format ("USER_SW_INTERRUPT");
|
||||
exc_code_SUPERVISOR_SW_INTERRUPT: $format ("SUPERVISOR_SW_INTERRUPT");
|
||||
exc_code_HYPERVISOR_SW_INTERRUPT: $format ("HYPERVISOR_SW_INTERRUPT");
|
||||
exc_code_MACHINE_SW_INTERRUPT: $format ("MACHINE_SW_INTERRUPT");
|
||||
exc_code_USER_SW_INTERRUPT: $format ("USER_SW_INTERRUPT");
|
||||
exc_code_SUPERVISOR_SW_INTERRUPT: $format ("SUPERVISOR_SW_INTERRUPT");
|
||||
exc_code_HYPERVISOR_SW_INTERRUPT: $format ("HYPERVISOR_SW_INTERRUPT");
|
||||
exc_code_MACHINE_SW_INTERRUPT: $format ("MACHINE_SW_INTERRUPT");
|
||||
|
||||
exc_code_USER_TIMER_INTERRUPT: $format ("USER_TIMER_INTERRUPT");
|
||||
exc_code_SUPERVISOR_TIMER_INTERRUPT: $format ("SUPERVISOR_TIMER_INTERRUPT");
|
||||
exc_code_HYPERVISOR_TIMER_INTERRUPT: $format ("HYPERVISOR_TIMER_INTERRUPT");
|
||||
exc_code_MACHINE_TIMER_INTERRUPT: $format ("MACHINE_TIMER_INTERRUPT");
|
||||
exc_code_USER_TIMER_INTERRUPT: $format ("USER_TIMER_INTERRUPT");
|
||||
exc_code_SUPERVISOR_TIMER_INTERRUPT: $format ("SUPERVISOR_TIMER_INTERRUPT");
|
||||
exc_code_HYPERVISOR_TIMER_INTERRUPT: $format ("HYPERVISOR_TIMER_INTERRUPT");
|
||||
exc_code_MACHINE_TIMER_INTERRUPT: $format ("MACHINE_TIMER_INTERRUPT");
|
||||
|
||||
exc_code_USER_EXTERNAL_INTERRUPT: $format ("USER_EXTERNAL_INTERRUPT");
|
||||
exc_code_SUPERVISOR_EXTERNAL_INTERRUPT: $format ("SUPERVISOR_EXTERNAL_INTERRUPT");
|
||||
exc_code_HYPERVISOR_EXTERNAL_INTERRUPT: $format ("HYPERVISOR_EXTERNAL_INTERRUPT");
|
||||
exc_code_MACHINE_EXTERNAL_INTERRUPT: $format ("MACHINE_EXTERNAL_INTERRUPT");
|
||||
default: $format ("unknown interrupt Exc_Code %d", exc_code);
|
||||
endcase;
|
||||
exc_code_USER_EXTERNAL_INTERRUPT: $format ("USER_EXTERNAL_INTERRUPT");
|
||||
exc_code_SUPERVISOR_EXTERNAL_INTERRUPT: $format ("SUPERVISOR_EXTERNAL_INTERRUPT");
|
||||
exc_code_HYPERVISOR_EXTERNAL_INTERRUPT: $format ("HYPERVISOR_EXTERNAL_INTERRUPT");
|
||||
exc_code_MACHINE_EXTERNAL_INTERRUPT: $format ("MACHINE_EXTERNAL_INTERRUPT");
|
||||
default: $format ("unknown interrupt Exc_Code %d", exc_code);
|
||||
endcase;
|
||||
endfunction
|
||||
|
||||
function Fmt fshow_trap_Exc_Code (Exc_Code exc_code);
|
||||
return case (exc_code)
|
||||
exc_code_INSTR_ADDR_MISALIGNED: $format ("INSTRUCTION_ADDR_MISALIGNED");
|
||||
exc_code_INSTR_ACCESS_FAULT: $format ("INSTRUCTION_ACCESS_FAULT");
|
||||
exc_code_ILLEGAL_INSTRUCTION: $format ("ILLEGAL_INSTRUCTION");
|
||||
exc_code_BREAKPOINT: $format ("BREAKPOINT");
|
||||
exc_code_INSTR_ADDR_MISALIGNED: $format ("INSTRUCTION_ADDR_MISALIGNED");
|
||||
exc_code_INSTR_ACCESS_FAULT: $format ("INSTRUCTION_ACCESS_FAULT");
|
||||
exc_code_ILLEGAL_INSTRUCTION: $format ("ILLEGAL_INSTRUCTION");
|
||||
exc_code_BREAKPOINT: $format ("BREAKPOINT");
|
||||
|
||||
exc_code_LOAD_ADDR_MISALIGNED: $format ("LOAD_ADDR_MISALIGNED");
|
||||
exc_code_LOAD_ACCESS_FAULT: $format ("LOAD_ACCESS_FAULT");
|
||||
exc_code_LOAD_ADDR_MISALIGNED: $format ("LOAD_ADDR_MISALIGNED");
|
||||
exc_code_LOAD_ACCESS_FAULT: $format ("LOAD_ACCESS_FAULT");
|
||||
|
||||
exc_code_STORE_AMO_ADDR_MISALIGNED: $format ("STORE_AMO_ADDR_MISALIGNED");
|
||||
exc_code_STORE_AMO_ACCESS_FAULT: $format ("STORE_AMO_ACCESS_FAULT");
|
||||
exc_code_STORE_AMO_ADDR_MISALIGNED: $format ("STORE_AMO_ADDR_MISALIGNED");
|
||||
exc_code_STORE_AMO_ACCESS_FAULT: $format ("STORE_AMO_ACCESS_FAULT");
|
||||
|
||||
exc_code_ECALL_FROM_U: $format ("ECALL_FROM_U");
|
||||
exc_code_ECALL_FROM_S: $format ("ECALL_FROM_S");
|
||||
exc_code_ECALL_FROM_M: $format ("ECALL_FROM_M");
|
||||
exc_code_ECALL_FROM_U: $format ("ECALL_FROM_U");
|
||||
exc_code_ECALL_FROM_S: $format ("ECALL_FROM_S");
|
||||
exc_code_ECALL_FROM_M: $format ("ECALL_FROM_M");
|
||||
|
||||
exc_code_INSTR_PAGE_FAULT: $format ("INSTRUCTION_PAGE_FAULT");
|
||||
exc_code_LOAD_PAGE_FAULT: $format ("LOAD_PAGE_FAULT");
|
||||
exc_code_STORE_AMO_PAGE_FAULT: $format ("STORE_AMO_PAGE_FAULT");
|
||||
exc_code_INSTR_PAGE_FAULT: $format ("INSTRUCTION_PAGE_FAULT");
|
||||
exc_code_LOAD_PAGE_FAULT: $format ("LOAD_PAGE_FAULT");
|
||||
exc_code_STORE_AMO_PAGE_FAULT: $format ("STORE_AMO_PAGE_FAULT");
|
||||
|
||||
default: $format ("unknown trap Exc_Code %d", exc_code);
|
||||
endcase;
|
||||
default: $format ("unknown trap Exc_Code %d", exc_code);
|
||||
endcase;
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -632,44 +632,44 @@ endfunction
|
||||
// and if so, corresponding exception code
|
||||
|
||||
function Maybe #(Exc_Code) fv_interrupt_pending (MISA misa,
|
||||
WordXL mstatus,
|
||||
WordXL mip,
|
||||
WordXL mie,
|
||||
Bit #(12) mideleg,
|
||||
Bit #(12) sideleg,
|
||||
Priv_Mode cur_priv);
|
||||
WordXL mstatus,
|
||||
WordXL mip,
|
||||
WordXL mie,
|
||||
Bit #(12) mideleg,
|
||||
Bit #(12) sideleg,
|
||||
Priv_Mode cur_priv);
|
||||
|
||||
function Maybe #(Exc_Code) fv_interrupt_i_pending (Exc_Code i);
|
||||
Bool intr_pending = ((mip [i] == 1) && (mie [i] == 1));
|
||||
Priv_Mode handler_priv;
|
||||
if (mideleg [i] == 1)
|
||||
if (misa.u == 1)
|
||||
if (misa.s == 1)
|
||||
// System with M, S, U
|
||||
if (sideleg [i] == 1)
|
||||
if (misa.n == 1)
|
||||
// M->S->U delegation
|
||||
handler_priv = u_Priv_Mode;
|
||||
else
|
||||
// Error: SIDELEG [i] should not be 1 if MISA.N is 0
|
||||
handler_priv = m_Priv_Mode;
|
||||
else
|
||||
if (misa.u == 1)
|
||||
if (misa.s == 1)
|
||||
// System with M, S, U
|
||||
if (sideleg [i] == 1)
|
||||
if (misa.n == 1)
|
||||
// M->S->U delegation
|
||||
handler_priv = u_Priv_Mode;
|
||||
else
|
||||
// Error: SIDELEG [i] should not be 1 if MISA.N is 0
|
||||
handler_priv = m_Priv_Mode;
|
||||
else
|
||||
// M->S delegation
|
||||
handler_priv = s_Priv_Mode;
|
||||
else
|
||||
// System with M, U
|
||||
if (misa.n == 1)
|
||||
// M->U delegation
|
||||
handler_priv = u_Priv_Mode;
|
||||
else
|
||||
// Error: MIDELEG [i] should not be 1 if MISA.N is 0
|
||||
handler_priv = m_Priv_Mode;
|
||||
else
|
||||
// Error: System with M only; MIDELEG [i] should not be 1
|
||||
handler_priv = m_Priv_Mode;
|
||||
handler_priv = s_Priv_Mode;
|
||||
else
|
||||
// System with M, U
|
||||
if (misa.n == 1)
|
||||
// M->U delegation
|
||||
handler_priv = u_Priv_Mode;
|
||||
else
|
||||
// Error: MIDELEG [i] should not be 1 if MISA.N is 0
|
||||
handler_priv = m_Priv_Mode;
|
||||
else
|
||||
// Error: System with M only; MIDELEG [i] should not be 1
|
||||
handler_priv = m_Priv_Mode;
|
||||
else
|
||||
// no delegation
|
||||
handler_priv = m_Priv_Mode;
|
||||
// no delegation
|
||||
handler_priv = m_Priv_Mode;
|
||||
|
||||
Bool xie;
|
||||
if (cur_priv == u_Priv_Mode)
|
||||
@@ -680,10 +680,10 @@ function Maybe #(Exc_Code) fv_interrupt_pending (MISA misa,
|
||||
xie = (mstatus [mstatus_mie_bitpos] == 1);
|
||||
else
|
||||
// Error: unexpected mode
|
||||
xie = False;
|
||||
xie = False;
|
||||
|
||||
Bool glob_enabled = ( (cur_priv < handler_priv)
|
||||
|| ((cur_priv == handler_priv) && xie));
|
||||
|| ((cur_priv == handler_priv) && xie));
|
||||
|
||||
return ((intr_pending && glob_enabled) ? (tagged Valid i) : (tagged Invalid));
|
||||
endfunction
|
||||
|
||||
@@ -342,19 +342,19 @@ endfunction
|
||||
|
||||
function Bool is_invalid_pte (PTE pte);
|
||||
return ( (fn_PTE_to_V (pte) == 0)
|
||||
|| ( (fn_PTE_to_R (pte) == 0)
|
||||
&& (fn_PTE_to_W (pte) == 1)));
|
||||
|| ( (fn_PTE_to_R (pte) == 0)
|
||||
&& (fn_PTE_to_W (pte) == 1)));
|
||||
endfunction
|
||||
|
||||
// ----------------
|
||||
// Check if PTE bits deny a virtual-mem access
|
||||
|
||||
function Bool is_pte_denial (Bool dmem_not_imem, // load-store or fetch?
|
||||
Bool read_not_write,
|
||||
Priv_Mode priv,
|
||||
Bit #(1) sstatus_SUM,
|
||||
Bit #(1) mstatus_MXR,
|
||||
PTE pte);
|
||||
Bool read_not_write,
|
||||
Priv_Mode priv,
|
||||
Bit #(1) sstatus_SUM,
|
||||
Bit #(1) mstatus_MXR,
|
||||
PTE pte);
|
||||
|
||||
let pte_u = fn_PTE_to_U (pte);
|
||||
let pte_x = fn_PTE_to_X (pte);
|
||||
@@ -362,7 +362,7 @@ function Bool is_pte_denial (Bool dmem_not_imem, // load-store or f
|
||||
let pte_r = fn_PTE_to_R (pte);
|
||||
|
||||
Bool priv_deny = ( ((priv == u_Priv_Mode) && (pte_u == 1'b0))
|
||||
|| ((priv == s_Priv_Mode) && (pte_u == 1'b1) && (sstatus_SUM == 1'b0)));
|
||||
|| ((priv == s_Priv_Mode) && (pte_u == 1'b1) && (sstatus_SUM == 1'b0)));
|
||||
|
||||
Bool access_fetch = ((! dmem_not_imem) && read_not_write);
|
||||
Bool access_load = (dmem_not_imem && read_not_write);
|
||||
@@ -371,8 +371,8 @@ function Bool is_pte_denial (Bool dmem_not_imem, // load-store or f
|
||||
let pte_r_mxr = (pte_r | (mstatus_MXR & pte_x));
|
||||
|
||||
Bool access_ok = ( (access_fetch && (pte_x == 1'b1))
|
||||
|| (access_load && (pte_r_mxr == 1'b1))
|
||||
|| (access_store && (pte_w == 1'b1)));
|
||||
|| (access_load && (pte_r_mxr == 1'b1))
|
||||
|| (access_store && (pte_w == 1'b1)));
|
||||
|
||||
|
||||
return (priv_deny || (! access_ok));
|
||||
@@ -383,7 +383,7 @@ endfunction
|
||||
|
||||
function Bool is_pte_A_D_fault (Bool read_not_write, PTE pte);
|
||||
return ( (fn_PTE_to_A (pte) == 0)
|
||||
|| ((! read_not_write) && (fn_PTE_to_D (pte) == 0)));
|
||||
|| ((! read_not_write) && (fn_PTE_to_D (pte) == 0)));
|
||||
endfunction
|
||||
|
||||
// ----------------
|
||||
@@ -391,8 +391,8 @@ endfunction
|
||||
|
||||
function Exc_Code fn_page_fault_exc_code (Bool dmem_not_imem, Bool read_not_write);
|
||||
return ((! dmem_not_imem) ? exc_code_INSTR_PAGE_FAULT
|
||||
:(read_not_write ? exc_code_LOAD_PAGE_FAULT
|
||||
: exc_code_STORE_AMO_PAGE_FAULT));
|
||||
:(read_not_write ? exc_code_LOAD_PAGE_FAULT
|
||||
: exc_code_STORE_AMO_PAGE_FAULT));
|
||||
endfunction
|
||||
|
||||
`else // ifdef ISA_PRIV_S
|
||||
@@ -414,8 +414,8 @@ endfunction
|
||||
|
||||
function Exc_Code fn_access_exc_code (Bool dmem_not_imem, Bool read_not_write);
|
||||
return ((! dmem_not_imem) ? exc_code_INSTR_ACCESS_FAULT
|
||||
:(read_not_write ? exc_code_LOAD_ACCESS_FAULT
|
||||
: exc_code_STORE_AMO_ACCESS_FAULT));
|
||||
:(read_not_write ? exc_code_LOAD_ACCESS_FAULT
|
||||
: exc_code_STORE_AMO_ACCESS_FAULT));
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
|
||||
@@ -25,25 +25,25 @@ import ISA_Decls :: *;
|
||||
// ================================================================
|
||||
|
||||
typedef enum {// These are not from instruction flow and do not have a PC or instruction
|
||||
TRACE_RESET,
|
||||
TRACE_GPR_WRITE,
|
||||
TRACE_FPR_WRITE,
|
||||
TRACE_CSR_WRITE,
|
||||
TRACE_MEM_WRITE,
|
||||
TRACE_RESET,
|
||||
TRACE_GPR_WRITE,
|
||||
TRACE_FPR_WRITE,
|
||||
TRACE_CSR_WRITE,
|
||||
TRACE_MEM_WRITE,
|
||||
|
||||
// These are from instruction flow and have a PC and instruction
|
||||
TRACE_OTHER,
|
||||
TRACE_I_RD, TRACE_F_GRD, TRACE_F_FRD,
|
||||
TRACE_I_LOAD, TRACE_F_LOAD,
|
||||
TRACE_I_STORE, TRACE_F_STORE,
|
||||
TRACE_AMO,
|
||||
TRACE_TRAP,
|
||||
TRACE_RET,
|
||||
TRACE_CSRRX,
|
||||
// These are from instruction flow and have a PC and instruction
|
||||
TRACE_OTHER,
|
||||
TRACE_I_RD, TRACE_F_GRD, TRACE_F_FRD,
|
||||
TRACE_I_LOAD, TRACE_F_LOAD,
|
||||
TRACE_I_STORE, TRACE_F_STORE,
|
||||
TRACE_AMO,
|
||||
TRACE_TRAP,
|
||||
TRACE_RET,
|
||||
TRACE_CSRRX,
|
||||
|
||||
// These are from an interrupt and has a PC but no instruction
|
||||
TRACE_INTR
|
||||
} Trace_Op
|
||||
// These are from an interrupt and has a PC but no instruction
|
||||
TRACE_INTR
|
||||
} Trace_Op
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
typedef struct {
|
||||
@@ -254,7 +254,7 @@ endfunction
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4
|
||||
// x x x x x rdval stval eaddr funct3
|
||||
function Trace_Data mkTrace_AMO (WordXL pc, Bit #(3) funct3, ISize isize, Bit #(32) instr,
|
||||
RegName rd, WordXL rdval, WordXL stval, WordXL eaddr);
|
||||
RegName rd, WordXL rdval, WordXL stval, WordXL eaddr);
|
||||
Trace_Data td = ?;
|
||||
td.op = TRACE_AMO;
|
||||
td.pc = pc;
|
||||
@@ -272,7 +272,7 @@ endfunction
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4
|
||||
// x x x x priv mstatus mcause mepc mtval
|
||||
function Trace_Data mkTrace_TRAP (WordXL pc, ISize isize, Bit #(32) instr,
|
||||
Priv_Mode priv, WordXL mstatus, WordXL mcause, WordXL mepc, WordXL mtval);
|
||||
Priv_Mode priv, WordXL mstatus, WordXL mcause, WordXL mepc, WordXL mtval);
|
||||
Trace_Data td = ?;
|
||||
td.op = TRACE_TRAP;
|
||||
td.pc = pc;
|
||||
@@ -305,10 +305,10 @@ endfunction
|
||||
// x x x x x rdval [1] mstatus_valid csraddr csrval mstatus
|
||||
// [0] csrvalid
|
||||
function Trace_Data mkTrace_CSRRX (WordXL pc, ISize isize, Bit #(32) instr,
|
||||
RegName rd, WordXL rdval,
|
||||
Bool csrvalid, CSR_Addr csraddr, WordXL csrval,
|
||||
Bool mstatus_valid,
|
||||
WordXL mstatus);
|
||||
RegName rd, WordXL rdval,
|
||||
Bool csrvalid, CSR_Addr csraddr, WordXL csrval,
|
||||
Bool mstatus_valid,
|
||||
WordXL mstatus);
|
||||
Trace_Data td = ?;
|
||||
td.op = TRACE_CSRRX;
|
||||
td.pc = pc;
|
||||
@@ -329,7 +329,7 @@ endfunction
|
||||
// op pc instr_sz instr rd word1 word2 word3 word4
|
||||
// x x priv mstatus mcause mepc mtval
|
||||
function Trace_Data mkTrace_INTR (WordXL pc,
|
||||
Priv_Mode priv, WordXL mstatus, WordXL mcause, WordXL mepc, WordXL mtval);
|
||||
Priv_Mode priv, WordXL mstatus, WordXL mcause, WordXL mepc, WordXL mtval);
|
||||
Trace_Data td = ?;
|
||||
td.op = TRACE_INTR;
|
||||
td.pc = pc;
|
||||
@@ -352,57 +352,57 @@ instance FShow #(Trace_Data);
|
||||
end
|
||||
|
||||
else if ((td.op == TRACE_GPR_WRITE) || (td.op == TRACE_FPR_WRITE))
|
||||
fmt = fmt + $format (" rd %0d rdval %0h", td.rd, td.word1);
|
||||
fmt = fmt + $format (" rd %0d rdval %0h", td.rd, td.word1);
|
||||
|
||||
else if (td.op == TRACE_CSR_WRITE)
|
||||
fmt = fmt + $format (" csraddr %0h csrval %0h", td.word3, td.word4);
|
||||
fmt = fmt + $format (" csraddr %0h csrval %0h", td.word3, td.word4);
|
||||
|
||||
else if (td.op == TRACE_MEM_WRITE)
|
||||
fmt = fmt + $format (" sz %0d stval %0h paddr %0h", td.word1, td.word2, td.word3);
|
||||
fmt = fmt + $format (" sz %0d stval %0h paddr %0h", td.word1, td.word2, td.word3);
|
||||
|
||||
else begin
|
||||
fmt = fmt + $format (" pc %0h", td.pc);
|
||||
fmt = fmt + $format (" pc %0h", td.pc);
|
||||
|
||||
if (td.op != TRACE_INTR)
|
||||
fmt = fmt + $format (" instr.%0d %0h:", pack (td.instr_sz), td.instr);
|
||||
if (td.op != TRACE_INTR)
|
||||
fmt = fmt + $format (" instr.%0d %0h:", pack (td.instr_sz), td.instr);
|
||||
|
||||
if (td.op == TRACE_I_RD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h", td.rd, td.word1);
|
||||
if (td.op == TRACE_I_RD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h", td.rd, td.word1);
|
||||
`ifdef ISA_F
|
||||
else if (td.op == TRACE_F_FRD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h fflags %05b", td.rd, td.word5, td.word2);
|
||||
else if (td.op == TRACE_F_FRD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h fflags %05b", td.rd, td.word5, td.word2);
|
||||
|
||||
else if (td.op == TRACE_F_GRD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h fflags %05b", td.rd, td.word1, td.word2);
|
||||
else if (td.op == TRACE_F_GRD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h fflags %05b", td.rd, td.word1, td.word2);
|
||||
|
||||
else if (td.op == TRACE_F_LOAD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h eaddr %0h",
|
||||
td.rd, td.word5, td.word3);
|
||||
else if (td.op == TRACE_F_LOAD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h eaddr %0h",
|
||||
td.rd, td.word5, td.word3);
|
||||
|
||||
else if (td.op == TRACE_F_STORE)
|
||||
fmt = fmt + $format (" stval %0h eaddr %0h", td.word5, td.word3);
|
||||
else if (td.op == TRACE_F_STORE)
|
||||
fmt = fmt + $format (" stval %0h eaddr %0h", td.word5, td.word3);
|
||||
`endif
|
||||
else if (td.op == TRACE_I_LOAD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h eaddr %0h",
|
||||
td.rd, td.word1, td.word3);
|
||||
else if (td.op == TRACE_I_LOAD)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h eaddr %0h",
|
||||
td.rd, td.word1, td.word3);
|
||||
|
||||
else if (td.op == TRACE_I_STORE)
|
||||
fmt = fmt + $format (" stval %0h eaddr %0h", td.word2, td.word3);
|
||||
else if (td.op == TRACE_I_STORE)
|
||||
fmt = fmt + $format (" stval %0h eaddr %0h", td.word2, td.word3);
|
||||
|
||||
else if (td.op == TRACE_AMO)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h stval %0h eaddr %0h",
|
||||
td.rd, td.word1, td.word2, td.word3);
|
||||
else if (td.op == TRACE_AMO)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h stval %0h eaddr %0h",
|
||||
td.rd, td.word1, td.word2, td.word3);
|
||||
|
||||
else if (td.op == TRACE_CSRRX)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h csraddr %0h csrval %0h",
|
||||
td.rd, td.word1, td.word3, td.word4);
|
||||
else if (td.op == TRACE_CSRRX)
|
||||
fmt = fmt + $format (" rd %0d rdval %0h csraddr %0h csrval %0h",
|
||||
td.rd, td.word1, td.word3, td.word4);
|
||||
|
||||
else if ((td.op == TRACE_TRAP) || (td.op == TRACE_INTR))
|
||||
fmt = fmt + $format (" priv %0d mstatus %0h mcause %0h mepc %0h mtval %0h",
|
||||
td.rd, td.word1, td.word2, td.word3, td.word4);
|
||||
else if ((td.op == TRACE_TRAP) || (td.op == TRACE_INTR))
|
||||
fmt = fmt + $format (" priv %0d mstatus %0h mcause %0h mepc %0h mtval %0h",
|
||||
td.rd, td.word1, td.word2, td.word3, td.word4);
|
||||
|
||||
else if (td.op == TRACE_RET)
|
||||
fmt = fmt + $format (" priv %0d mstatus %0h", td.rd, td.word1);
|
||||
else if (td.op == TRACE_RET)
|
||||
fmt = fmt + $format (" priv %0d mstatus %0h", td.rd, td.word1);
|
||||
end
|
||||
|
||||
fmt = fmt + $format ("}");
|
||||
|
||||
@@ -71,8 +71,8 @@ endinterface
|
||||
// PLIC interface
|
||||
|
||||
interface PLIC_IFC #(numeric type t_n_external_sources,
|
||||
numeric type t_n_targets,
|
||||
numeric type t_max_priority);
|
||||
numeric type t_n_targets,
|
||||
numeric type t_max_priority);
|
||||
// Debugging
|
||||
method Action set_verbosity (Bit #(4) verbosity);
|
||||
method Action show_PLIC_state;
|
||||
@@ -98,9 +98,9 @@ endinterface
|
||||
|
||||
module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
provisos (Add #(1, t_n_external_sources, t_n_sources), // source 0 is reserved for 'no source'
|
||||
Add #(_any_0, TLog #(t_n_sources), T_wd_source_id),
|
||||
Add #(_any_1, TLog #(t_n_targets), T_wd_target_id),
|
||||
Log #(TAdd #(t_max_priority, 1), t_wd_priority));
|
||||
Add #(_any_0, TLog #(t_n_sources), T_wd_source_id),
|
||||
Add #(_any_1, TLog #(t_n_targets), T_wd_target_id),
|
||||
Log #(TAdd #(t_max_priority, 1), t_wd_priority));
|
||||
|
||||
// 0 = quiet; 1 = show PLIC transactions; 2 = also show AXI4 transactions
|
||||
Reg #(Bit #(4)) cfg_verbosity <- mkConfigReg (0);
|
||||
@@ -151,7 +151,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
// Interrupt enables from source to target
|
||||
Vector #(t_n_targets,
|
||||
Vector #(t_n_sources, Reg #(Bool))) vvrg_ie <- replicateM (replicateM (mkReg (False)));
|
||||
Vector #(t_n_sources, Reg #(Bool))) vvrg_ie <- replicateM (replicateM (mkReg (False)));
|
||||
|
||||
// ================================================================
|
||||
// Compute outputs for each target (combinational)
|
||||
@@ -164,42 +164,42 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
// Note: source_ids begin at 1, not 0.
|
||||
for (Integer source_id = 1; source_id < n_sources; source_id = source_id + 1)
|
||||
if ( vrg_source_ip [source_id]
|
||||
&& (vrg_source_prio [source_id] > max_prio)
|
||||
&& (vvrg_ie [target_id][source_id])) begin
|
||||
max_id = fromInteger (source_id);
|
||||
max_prio = vrg_source_prio [source_id];
|
||||
end
|
||||
if ( vrg_source_ip [source_id]
|
||||
&& (vrg_source_prio [source_id] > max_prio)
|
||||
&& (vvrg_ie [target_id][source_id])) begin
|
||||
max_id = fromInteger (source_id);
|
||||
max_prio = vrg_source_prio [source_id];
|
||||
end
|
||||
// Assert: if any interrupt is pending (max_id > 0), then prio > 0
|
||||
return tuple2 (max_prio, max_id);
|
||||
endfunction
|
||||
|
||||
function Action fa_show_PLIC_state;
|
||||
action
|
||||
$display ("----------------");
|
||||
$write ("Src IPs :");
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", pack (vrg_source_ip [source_id]));
|
||||
$display ("");
|
||||
$display ("----------------");
|
||||
$write ("Src IPs :");
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", pack (vrg_source_ip [source_id]));
|
||||
$display ("");
|
||||
|
||||
$write ("Src Prios:");
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", vrg_source_prio [source_id]);
|
||||
$display ("");
|
||||
$write ("Src Prios:");
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", vrg_source_prio [source_id]);
|
||||
$display ("");
|
||||
|
||||
$write ("Src busy :");
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", pack (vrg_source_busy [source_id]));
|
||||
$display ("");
|
||||
$write ("Src busy :");
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", pack (vrg_source_busy [source_id]));
|
||||
$display ("");
|
||||
|
||||
for (Integer target_id = 0; target_id < n_targets; target_id = target_id + 1) begin
|
||||
$write ("T %0d IEs :", target_id);
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", vvrg_ie [target_id][source_id]);
|
||||
match { .max_prio, .max_id } = fn_target_max_prio_and_max_id (fromInteger (target_id));
|
||||
$display (" MaxPri %0d, Thresh %0d, MaxId %0d, Svcing %0d",
|
||||
max_prio, vrg_target_threshold [target_id], max_id, vrg_servicing_source [target_id]);
|
||||
end
|
||||
for (Integer target_id = 0; target_id < n_targets; target_id = target_id + 1) begin
|
||||
$write ("T %0d IEs :", target_id);
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
$write (" %0d", vvrg_ie [target_id][source_id]);
|
||||
match { .max_prio, .max_id } = fn_target_max_prio_and_max_id (fromInteger (target_id));
|
||||
$display (" MaxPri %0d, Thresh %0d, MaxId %0d, Svcing %0d",
|
||||
max_prio, vrg_target_threshold [target_id], max_id, vrg_servicing_source [target_id]);
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -208,25 +208,25 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
rule rl_reset;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_reset", cur_cycle);
|
||||
$display ("%0d: PLIC.rl_reset", cur_cycle);
|
||||
|
||||
let x <- pop (f_reset_reqs);
|
||||
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1) begin
|
||||
vrg_source_ip [source_id] <= False;
|
||||
vrg_source_busy [source_id] <= False;
|
||||
vrg_source_prio [source_id] <= 0;
|
||||
vrg_source_ip [source_id] <= False;
|
||||
vrg_source_busy [source_id] <= False;
|
||||
vrg_source_prio [source_id] <= 0;
|
||||
end
|
||||
|
||||
for (Integer target_id = 0; target_id < n_targets; target_id = target_id + 1) begin
|
||||
// Mask all interrupts with highest threshold
|
||||
vrg_target_threshold [target_id] <= '1;
|
||||
vrg_servicing_source [target_id] <= 0;
|
||||
// Mask all interrupts with highest threshold
|
||||
vrg_target_threshold [target_id] <= '1;
|
||||
vrg_servicing_source [target_id] <= 0;
|
||||
end
|
||||
|
||||
for (Integer target_id = 0; target_id < n_targets; target_id = target_id + 1)
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
vvrg_ie [target_id][source_id] <= False;
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
vvrg_ie [target_id][source_id] <= False;
|
||||
|
||||
slave_xactor.reset;
|
||||
|
||||
@@ -245,8 +245,8 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
let rda <- pop_o (slave_xactor.o_rd_addr);
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: PLIC.rl_process_rd_req:", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
$display ("%0d: PLIC.rl_process_rd_req:", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
end
|
||||
|
||||
let addr_offset = rda.araddr - rg_addr_base;
|
||||
@@ -254,148 +254,148 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
AXI4_Resp rresp = axi4_resp_okay;
|
||||
|
||||
if (rda.araddr < rg_addr_base) begin
|
||||
// Technically this should not happen: the fabric should
|
||||
// never have delivered such an addr to this IP.
|
||||
$display ("%0d: ERROR: PLIC.rl_process_rd_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
rresp = axi4_resp_decerr;
|
||||
// Technically this should not happen: the fabric should
|
||||
// never have delivered such an addr to this IP.
|
||||
$display ("%0d: ERROR: PLIC.rl_process_rd_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
rresp = axi4_resp_decerr;
|
||||
end
|
||||
|
||||
// Source Priority
|
||||
else if (addr_offset < 'h1000) begin
|
||||
Bit #(T_wd_source_id) source_id = truncate (addr_offset [11:2]);
|
||||
if ((0 < source_id) && (source_id <= fromInteger (n_sources - 1))) begin
|
||||
rdata = changeWidth (vrg_source_prio [source_id]);
|
||||
Bit #(T_wd_source_id) source_id = truncate (addr_offset [11:2]);
|
||||
if ((0 < source_id) && (source_id <= fromInteger (n_sources - 1))) begin
|
||||
rdata = changeWidth (vrg_source_prio [source_id]);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Source Priority: source %0d = 0x%0h",
|
||||
cur_cycle, source_id, rdata);
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Source Priority: source %0d = 0x%0h",
|
||||
cur_cycle, source_id, rdata);
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
end
|
||||
|
||||
// Source IPs (interrupt pending).
|
||||
// Return 32 consecutive IP bits starting with addr.
|
||||
else if (('h1000 <= addr_offset) && (addr_offset < 'h2000)) begin
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [11:0], 5'h0 });
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [11:0], 5'h0 });
|
||||
|
||||
function Bool fn_ip_source_id (Integer source_id_offset);
|
||||
let source_id = source_id_base + fromInteger (source_id_offset);
|
||||
Bool ip_source_id = ( (source_id <= fromInteger (n_sources - 1))
|
||||
? vrg_source_ip [source_id]
|
||||
: False);
|
||||
return ip_source_id;
|
||||
endfunction
|
||||
function Bool fn_ip_source_id (Integer source_id_offset);
|
||||
let source_id = source_id_base + fromInteger (source_id_offset);
|
||||
Bool ip_source_id = ( (source_id <= fromInteger (n_sources - 1))
|
||||
? vrg_source_ip [source_id]
|
||||
: False);
|
||||
return ip_source_id;
|
||||
endfunction
|
||||
|
||||
if (source_id_base <= fromInteger (n_sources - 1)) begin
|
||||
Bit #(32) v_ip = pack (genWith (fn_ip_source_id));
|
||||
rdata = changeWidth (v_ip);
|
||||
if (source_id_base <= fromInteger (n_sources - 1)) begin
|
||||
Bit #(32) v_ip = pack (genWith (fn_ip_source_id));
|
||||
rdata = changeWidth (v_ip);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Intr Pending 32 bits from source %0d = 0x%0h",
|
||||
cur_cycle, source_id_base, rdata);
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Intr Pending 32 bits from source %0d = 0x%0h",
|
||||
cur_cycle, source_id_base, rdata);
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
end
|
||||
|
||||
// Source IEs (interrupt enables) for a target
|
||||
// Return 32 consecutive IE bits starting with addr.
|
||||
// Target 0 addrs: 2000-207F, Target 1 addrs: 2080-20FF, ...
|
||||
else if (('h2000 <= addr_offset) && (addr_offset < 'h3000)) begin
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [11:7]);
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [6:0], 5'h0 });
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [11:7]);
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [6:0], 5'h0 });
|
||||
|
||||
function Bool fn_ie_source_id (Integer source_id_offset);
|
||||
let source_id = fromInteger (source_id_offset) + source_id_base;
|
||||
return ( (source_id <= fromInteger (n_sources - 1))
|
||||
? vvrg_ie [target_id][source_id]
|
||||
: False);
|
||||
endfunction
|
||||
function Bool fn_ie_source_id (Integer source_id_offset);
|
||||
let source_id = fromInteger (source_id_offset) + source_id_base;
|
||||
return ( (source_id <= fromInteger (n_sources - 1))
|
||||
? vvrg_ie [target_id][source_id]
|
||||
: False);
|
||||
endfunction
|
||||
|
||||
if ( (source_id_base <= fromInteger (n_sources - 1))
|
||||
&& (target_id <= fromInteger (n_targets - 1))) begin
|
||||
Bit #(32) v_ie = pack (genWith (fn_ie_source_id));
|
||||
rdata = changeWidth (v_ie);
|
||||
if ( (source_id_base <= fromInteger (n_sources - 1))
|
||||
&& (target_id <= fromInteger (n_targets - 1))) begin
|
||||
Bit #(32) v_ie = pack (genWith (fn_ie_source_id));
|
||||
rdata = changeWidth (v_ie);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Intr Enable 32 bits from source %0d = 0x%0h",
|
||||
cur_cycle, source_id_base, rdata);
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Intr Enable 32 bits from source %0d = 0x%0h",
|
||||
cur_cycle, source_id_base, rdata);
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
end
|
||||
|
||||
// Target threshold
|
||||
else if ((addr_offset [31:0] & 32'hFFFF_0FFF) == 32'h0020_0000) begin
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
rdata = changeWidth (vrg_target_threshold [target_id]);
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
rdata = changeWidth (vrg_target_threshold [target_id]);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Threshold for target %0d = 0x%0h",
|
||||
cur_cycle, target_id, rdata);
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Threshold for target %0d = 0x%0h",
|
||||
cur_cycle, target_id, rdata);
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
end
|
||||
|
||||
// Interrupt service claim by target
|
||||
else if ((addr_offset [31:0] & 32'hFFFF_0FFF) == 32'h0020_0004) begin
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
match { .max_prio, .max_id } = fn_target_max_prio_and_max_id (target_id);
|
||||
Bool eip = (max_prio > vrg_target_threshold [target_id]);
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
if (vrg_servicing_source [target_id] != 0) begin
|
||||
$display ("%0d: ERROR: PLIC: target %0d claiming without prior completion",
|
||||
cur_cycle, target_id);
|
||||
$display (" Still servicing interrupt from source %0d", vrg_servicing_source [target_id]);
|
||||
$display (" Trying to claim service for source %0d", max_id);
|
||||
$display (" Ignoring.");
|
||||
rresp = axi4_resp_slverr;
|
||||
end
|
||||
else begin
|
||||
if (max_id != 0) begin
|
||||
vrg_source_ip [max_id] <= False;
|
||||
vrg_source_busy [max_id] <= True;
|
||||
vrg_servicing_source [target_id] <= truncate (max_id);
|
||||
rdata = changeWidth (max_id);
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
match { .max_prio, .max_id } = fn_target_max_prio_and_max_id (target_id);
|
||||
Bool eip = (max_prio > vrg_target_threshold [target_id]);
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
if (vrg_servicing_source [target_id] != 0) begin
|
||||
$display ("%0d: ERROR: PLIC: target %0d claiming without prior completion",
|
||||
cur_cycle, target_id);
|
||||
$display (" Still servicing interrupt from source %0d", vrg_servicing_source [target_id]);
|
||||
$display (" Trying to claim service for source %0d", max_id);
|
||||
$display (" Ignoring.");
|
||||
rresp = axi4_resp_slverr;
|
||||
end
|
||||
else begin
|
||||
if (max_id != 0) begin
|
||||
vrg_source_ip [max_id] <= False;
|
||||
vrg_source_busy [max_id] <= True;
|
||||
vrg_servicing_source [target_id] <= truncate (max_id);
|
||||
rdata = changeWidth (max_id);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Claim for target %0d = 0x%0h",
|
||||
cur_cycle, target_id, rdata);
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_rd_req: reading Claim for target %0d = 0x%0h",
|
||||
cur_cycle, target_id, rdata);
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
end
|
||||
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
rresp = axi4_resp_slverr;
|
||||
|
||||
if (rresp != axi4_resp_okay) begin
|
||||
$display ("%0d: ERROR: PLIC.rl_process_rd_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
$display ("%0d: ERROR: PLIC.rl_process_rd_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
end
|
||||
|
||||
if ((valueOf (Wd_Data) == 64) && ((addr_offset & 'h7) == 'h4))
|
||||
rdata = { rdata [31:0], 32'h0 };
|
||||
rdata = { rdata [31:0], 32'h0 };
|
||||
|
||||
// Send read-response to bus
|
||||
Fabric_Data x = truncate (rdata);
|
||||
let rdr = AXI4_Rd_Data {rid: rda.arid,
|
||||
rdata: x,
|
||||
rresp: rresp,
|
||||
rlast: True,
|
||||
ruser: rda.aruser};
|
||||
rdata: x,
|
||||
rresp: rresp,
|
||||
rlast: True,
|
||||
ruser: rda.aruser};
|
||||
slave_xactor.i_rd_data.enq (rdr);
|
||||
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: PLIC.rl_process_rd_req", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
$display (" ", fshow (rdr));
|
||||
$display ("%0d: PLIC.rl_process_rd_req", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
$display (" ", fshow (rdr));
|
||||
end
|
||||
endrule: rl_process_rd_req
|
||||
|
||||
@@ -409,139 +409,139 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
let wra <- pop_o (slave_xactor.o_wr_addr);
|
||||
let wrd <- pop_o (slave_xactor.o_wr_data);
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: PLIC.rl_process_wr_req", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
$display ("%0d: PLIC.rl_process_wr_req", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
end
|
||||
|
||||
let addr_offset = wra.awaddr - rg_addr_base;
|
||||
let wdata32 = (((valueOf (Wd_Data) == 64) && ((addr_offset & 'h7) == 'h4))
|
||||
? wrd.wdata [63:32]
|
||||
: wrd.wdata [31:0]);
|
||||
? wrd.wdata [63:32]
|
||||
: wrd.wdata [31:0]);
|
||||
let bresp = axi4_resp_okay;
|
||||
|
||||
if (wra.awaddr < rg_addr_base) begin
|
||||
// Technically this should not happen: the fabric should
|
||||
// never have delivered such an addr to this IP.
|
||||
$display ("%0d: ERROR: PLIC.rl_process_wr_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
bresp = axi4_resp_decerr;
|
||||
// Technically this should not happen: the fabric should
|
||||
// never have delivered such an addr to this IP.
|
||||
$display ("%0d: ERROR: PLIC.rl_process_wr_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
bresp = axi4_resp_decerr;
|
||||
end
|
||||
|
||||
// Source priority
|
||||
else if (addr_offset < 'h1000) begin
|
||||
Bit #(T_wd_source_id) source_id = truncate (addr_offset [11:2]);
|
||||
if ((0 < source_id) && (source_id <= fromInteger (n_sources - 1))) begin
|
||||
vrg_source_prio [source_id] <= changeWidth (wdata32);
|
||||
Bit #(T_wd_source_id) source_id = truncate (addr_offset [11:2]);
|
||||
if ((0 < source_id) && (source_id <= fromInteger (n_sources - 1))) begin
|
||||
vrg_source_prio [source_id] <= changeWidth (wdata32);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing Source Priority: source %0d = 0x%0h",
|
||||
cur_cycle, source_id, wdata32);
|
||||
end
|
||||
else begin
|
||||
// Note: write to source_id 0 is error; should it just be ignored?
|
||||
bresp = axi4_resp_slverr;
|
||||
end
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing Source Priority: source %0d = 0x%0h",
|
||||
cur_cycle, source_id, wdata32);
|
||||
end
|
||||
else begin
|
||||
// Note: write to source_id 0 is error; should it just be ignored?
|
||||
bresp = axi4_resp_slverr;
|
||||
end
|
||||
end
|
||||
|
||||
// Source IPs (interrupt pending).
|
||||
// Read-only, so ignore write; just check that addr ok.
|
||||
else if (('h1000 <= addr_offset) && (addr_offset < 'h2000)) begin
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [11:0], 5'h0 });
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [11:0], 5'h0 });
|
||||
|
||||
if (source_id_base <= fromInteger (n_sources - 1)) begin
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: Ignoring write to Read-only Intr Pending 32 bits from source %0d",
|
||||
cur_cycle, source_id_base);
|
||||
end
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
if (source_id_base <= fromInteger (n_sources - 1)) begin
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: Ignoring write to Read-only Intr Pending 32 bits from source %0d",
|
||||
cur_cycle, source_id_base);
|
||||
end
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
end
|
||||
|
||||
// Source IEs (interrupt enables) for a target
|
||||
// Write 32 consecutive IE bits starting with addr.
|
||||
// Target 0 addrs: 2000-207F, Target 1 addrs: 2080-20FF, ...
|
||||
else if (('h2000 <= addr_offset) && (addr_offset < 'h3000)) begin
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [11:7]);
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [6:0], 5'h0 });
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [11:7]);
|
||||
Bit #(T_wd_source_id) source_id_base = truncate ({ addr_offset [6:0], 5'h0 });
|
||||
|
||||
if ( (source_id_base <= fromInteger (n_sources - 1))
|
||||
&& (target_id <= fromInteger (n_targets - 1))) begin
|
||||
for (Bit #(T_wd_source_id) k = 0; k < 32; k = k + 1) begin
|
||||
Bit #(T_wd_source_id) source_id = source_id_base + k;
|
||||
if (source_id <= fromInteger (n_sources - 1))
|
||||
vvrg_ie [target_id][source_id] <= unpack (wdata32 [k]);
|
||||
end
|
||||
if ( (source_id_base <= fromInteger (n_sources - 1))
|
||||
&& (target_id <= fromInteger (n_targets - 1))) begin
|
||||
for (Bit #(T_wd_source_id) k = 0; k < 32; k = k + 1) begin
|
||||
Bit #(T_wd_source_id) source_id = source_id_base + k;
|
||||
if (source_id <= fromInteger (n_sources - 1))
|
||||
vvrg_ie [target_id][source_id] <= unpack (wdata32 [k]);
|
||||
end
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing Intr Enable 32 bits for target %0d from source %0d = 0x%0h",
|
||||
cur_cycle, target_id, source_id_base, wdata32);
|
||||
end
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing Intr Enable 32 bits for target %0d from source %0d = 0x%0h",
|
||||
cur_cycle, target_id, source_id_base, wdata32);
|
||||
end
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
end
|
||||
|
||||
// Target threshold
|
||||
else if ((addr_offset [31:0] & 32'hFFFF_0FFF) == 32'h0020_0000) begin
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
vrg_target_threshold [target_id] <= changeWidth (wdata32);
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
vrg_target_threshold [target_id] <= changeWidth (wdata32);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing threshold for target %0d = 0x%0h",
|
||||
cur_cycle, target_id, wdata32);
|
||||
end
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing threshold for target %0d = 0x%0h",
|
||||
cur_cycle, target_id, wdata32);
|
||||
end
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
end
|
||||
|
||||
// Interrupt service completion by target
|
||||
// Actual memory-write-data is irrelevant.
|
||||
else if ((addr_offset [31:0] & 32'hFFFF_0FFF) == 32'h0020_0004) begin
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
Bit #(T_wd_source_id) source_id = zeroExtend (vrg_servicing_source [target_id]);
|
||||
Bit #(T_wd_target_id) target_id = truncate (addr_offset [20:12]);
|
||||
Bit #(T_wd_source_id) source_id = zeroExtend (vrg_servicing_source [target_id]);
|
||||
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
if (vrg_source_busy [source_id]) begin
|
||||
vrg_source_busy [source_id] <= False;
|
||||
vrg_servicing_source [target_id] <= 0;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing completion for target %0d for source 0x%0h",
|
||||
cur_cycle, target_id, source_id);
|
||||
end
|
||||
else begin
|
||||
$display ("%0d: ERROR: PLIC: interrupt completion to source that is not being serviced",
|
||||
cur_cycle);
|
||||
$display (" Completion message from target %0d to source %0d", target_id, source_id);
|
||||
$display (" Ignoring");
|
||||
bresp = axi4_resp_slverr;
|
||||
end
|
||||
end
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
if (target_id <= fromInteger (n_targets - 1)) begin
|
||||
if (vrg_source_busy [source_id]) begin
|
||||
vrg_source_busy [source_id] <= False;
|
||||
vrg_servicing_source [target_id] <= 0;
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.rl_process_wr_req: writing completion for target %0d for source 0x%0h",
|
||||
cur_cycle, target_id, source_id);
|
||||
end
|
||||
else begin
|
||||
$display ("%0d: ERROR: PLIC: interrupt completion to source that is not being serviced",
|
||||
cur_cycle);
|
||||
$display (" Completion message from target %0d to source %0d", target_id, source_id);
|
||||
$display (" Ignoring");
|
||||
bresp = axi4_resp_slverr;
|
||||
end
|
||||
end
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
end
|
||||
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
bresp = axi4_resp_slverr;
|
||||
|
||||
if (bresp != axi4_resp_okay) begin
|
||||
$display ("%0d: ERROR: PLIC.rl_process_wr_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
$display ("%0d: ERROR: PLIC.rl_process_wr_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
end
|
||||
|
||||
// Send write-response to bus
|
||||
let wrr = AXI4_Wr_Resp {bid: wra.awid,
|
||||
bresp: bresp,
|
||||
buser: wra.awuser};
|
||||
bresp: bresp,
|
||||
buser: wra.awuser};
|
||||
slave_xactor.i_wr_resp.enq (wrr);
|
||||
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: PLIC.AXI4.rl_process_wr_req", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
$display (" ", fshow (wrr));
|
||||
$display ("%0d: PLIC.AXI4.rl_process_wr_req", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
$display (" ", fshow (wrr));
|
||||
end
|
||||
endrule: rl_process_wr_req
|
||||
|
||||
@@ -550,18 +550,18 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
function PLIC_Source_IFC fn_mk_PLIC_Source_IFC (Integer source_id);
|
||||
return interface PLIC_Source_IFC;
|
||||
method Action m_interrupt_req (Bool set_not_clear);
|
||||
action
|
||||
if (! vrg_source_busy [source_id + 1]) begin
|
||||
vrg_source_ip [source_id + 1] <= set_not_clear;
|
||||
method Action m_interrupt_req (Bool set_not_clear);
|
||||
action
|
||||
if (! vrg_source_busy [source_id + 1]) begin
|
||||
vrg_source_ip [source_id + 1] <= set_not_clear;
|
||||
|
||||
if ((cfg_verbosity > 0) && (vrg_source_ip [source_id + 1] != set_not_clear))
|
||||
$display ("%0d: %m.m_interrupt_req: changing vrg_source_ip [%0d] to %0d",
|
||||
cur_cycle, source_id + 1, pack (set_not_clear));
|
||||
end
|
||||
endaction
|
||||
endmethod
|
||||
endinterface;
|
||||
if ((cfg_verbosity > 0) && (vrg_source_ip [source_id + 1] != set_not_clear))
|
||||
$display ("%0d: %m.m_interrupt_req: changing vrg_source_ip [%0d] to %0d",
|
||||
cur_cycle, source_id + 1, pack (set_not_clear));
|
||||
end
|
||||
endaction
|
||||
endmethod
|
||||
endinterface;
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -569,12 +569,12 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
function PLIC_Target_IFC fn_mk_PLIC_Target_IFC (Integer target_id);
|
||||
return interface PLIC_Target_IFC;
|
||||
method Bool m_eip; // external interrupt pending
|
||||
match { .max_prio, .max_id } = fn_target_max_prio_and_max_id (fromInteger (target_id));
|
||||
Bool eip = (max_prio > vrg_target_threshold [target_id]);
|
||||
return eip;
|
||||
endmethod
|
||||
endinterface;
|
||||
method Bool m_eip; // external interrupt pending
|
||||
match { .max_prio, .max_id } = fn_target_max_prio_and_max_id (fromInteger (target_id));
|
||||
Bool eip = (max_prio > vrg_target_threshold [target_id]);
|
||||
return eip;
|
||||
endmethod
|
||||
endinterface;
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -595,18 +595,18 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
// set_addr_map should be called after this module's reset
|
||||
method Action set_addr_map (Bit #(64) addr_base, Bit #(64) addr_lim);
|
||||
if (addr_base [1:0] != 0)
|
||||
$display ("%0d: WARNING: PLIC.set_addr_map: addr_base 0x%0h is not 4-Byte-aligned",
|
||||
cur_cycle, addr_base);
|
||||
$display ("%0d: WARNING: PLIC.set_addr_map: addr_base 0x%0h is not 4-Byte-aligned",
|
||||
cur_cycle, addr_base);
|
||||
|
||||
if (addr_lim [1:0] != 0)
|
||||
$display ("%0d: WARNING: PLIC.set_addr_map: addr_lim 0x%0h is not 4-Byte-aligned",
|
||||
cur_cycle, addr_lim);
|
||||
$display ("%0d: WARNING: PLIC.set_addr_map: addr_lim 0x%0h is not 4-Byte-aligned",
|
||||
cur_cycle, addr_lim);
|
||||
|
||||
rg_addr_base <= addr_base;
|
||||
rg_addr_lim <= addr_lim;
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
$display ("%0d: PLIC.set_addr_map: base 0x%0h limit 0x%0h", cur_cycle, addr_base, addr_lim);
|
||||
$display ("%0d: PLIC.set_addr_map: base 0x%0h limit 0x%0h", cur_cycle, addr_base, addr_lim);
|
||||
endmethod
|
||||
|
||||
// Memory-mapped access
|
||||
|
||||
@@ -28,8 +28,8 @@ typedef 2 PLIC_N_Targets;
|
||||
typedef 7 PLIC_Max_Priority;
|
||||
|
||||
typedef PLIC_IFC #(N_External_Interrupt_Sources,
|
||||
PLIC_N_Targets,
|
||||
PLIC_Max_Priority) PLIC_IFC_16_2_7;
|
||||
PLIC_N_Targets,
|
||||
PLIC_Max_Priority) PLIC_IFC_16_2_7;
|
||||
|
||||
(* synthesize *)
|
||||
module mkPLIC_16_2_7 (PLIC_IFC_16_2_7);
|
||||
|
||||
@@ -72,76 +72,76 @@ module mkTest_PLIC (Empty);
|
||||
|
||||
function Action fa_read_req (Integer addr);
|
||||
action
|
||||
let fabric_addr = soc_map.m_plic_addr_base + fromInteger (addr);
|
||||
let fabric_addr = soc_map.m_plic_addr_base + fromInteger (addr);
|
||||
|
||||
let mem_req_rd_addr = AXI4_Rd_Addr {arid: fabric_default_id,
|
||||
araddr: fabric_addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: zeroExtend (axsize_4),
|
||||
arburst: fabric_default_burst,
|
||||
arlock: fabric_default_lock,
|
||||
arcache: fabric_default_arcache,
|
||||
arprot: fabric_default_prot,
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_user};
|
||||
master_xactor.i_rd_addr.enq (mem_req_rd_addr);
|
||||
f_read_addr.enq (fabric_addr);
|
||||
let mem_req_rd_addr = AXI4_Rd_Addr {arid: fabric_default_id,
|
||||
araddr: fabric_addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: zeroExtend (axsize_4),
|
||||
arburst: fabric_default_burst,
|
||||
arlock: fabric_default_lock,
|
||||
arcache: fabric_default_arcache,
|
||||
arprot: fabric_default_prot,
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_user};
|
||||
master_xactor.i_rd_addr.enq (mem_req_rd_addr);
|
||||
f_read_addr.enq (fabric_addr);
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
function Action fa_read_rsp;
|
||||
action
|
||||
let fabric_addr <- pop (f_read_addr);
|
||||
let rd_data <- pop_o (master_xactor.o_rd_data);
|
||||
if (rd_data.rresp != axi4_resp_okay) begin
|
||||
$display ("ERROR: fa_read_rsp: fabric response error");
|
||||
$display (" ", fshow (rd_data));
|
||||
end
|
||||
let x = (((valueOf (Wd_Data) == 64) && ((fabric_addr & 'h7) == 'h4))
|
||||
? (rd_data.rdata >> 32)
|
||||
: rd_data.rdata);
|
||||
f_read_data.enq (x);
|
||||
let fabric_addr <- pop (f_read_addr);
|
||||
let rd_data <- pop_o (master_xactor.o_rd_data);
|
||||
if (rd_data.rresp != axi4_resp_okay) begin
|
||||
$display ("ERROR: fa_read_rsp: fabric response error");
|
||||
$display (" ", fshow (rd_data));
|
||||
end
|
||||
let x = (((valueOf (Wd_Data) == 64) && ((fabric_addr & 'h7) == 'h4))
|
||||
? (rd_data.rdata >> 32)
|
||||
: rd_data.rdata);
|
||||
f_read_data.enq (x);
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
function Action fa_write_req (Integer addr, Fabric_Data data);
|
||||
action
|
||||
let fabric_addr = soc_map.m_plic_addr_base + fromInteger (addr);
|
||||
let fabric_addr = soc_map.m_plic_addr_base + fromInteger (addr);
|
||||
|
||||
let mem_req_wr_addr = AXI4_Wr_Addr {awid: fabric_default_id,
|
||||
awaddr: fabric_addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: zeroExtend (axsize_4),
|
||||
awburst: fabric_default_burst,
|
||||
awlock: fabric_default_lock,
|
||||
awcache: fabric_default_awcache,
|
||||
awprot: fabric_default_prot,
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: fabric_default_user};
|
||||
let mem_req_wr_addr = AXI4_Wr_Addr {awid: fabric_default_id,
|
||||
awaddr: fabric_addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: zeroExtend (axsize_4),
|
||||
awburst: fabric_default_burst,
|
||||
awlock: fabric_default_lock,
|
||||
awcache: fabric_default_awcache,
|
||||
awprot: fabric_default_prot,
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: fabric_default_user};
|
||||
|
||||
let x = (((valueOf (Wd_Data) == 64) && ((fabric_addr & 'h7) == 'h4))
|
||||
? (data << 32)
|
||||
: data);
|
||||
let mem_req_wr_data = AXI4_Wr_Data {wid: fabric_default_id,
|
||||
wdata: x,
|
||||
wstrb: '1,
|
||||
wlast: True,
|
||||
wuser: fabric_default_user};
|
||||
master_xactor.i_wr_addr.enq (mem_req_wr_addr);
|
||||
master_xactor.i_wr_data.enq (mem_req_wr_data);
|
||||
let x = (((valueOf (Wd_Data) == 64) && ((fabric_addr & 'h7) == 'h4))
|
||||
? (data << 32)
|
||||
: data);
|
||||
let mem_req_wr_data = AXI4_Wr_Data {wid: fabric_default_id,
|
||||
wdata: x,
|
||||
wstrb: '1,
|
||||
wlast: True,
|
||||
wuser: fabric_default_user};
|
||||
master_xactor.i_wr_addr.enq (mem_req_wr_addr);
|
||||
master_xactor.i_wr_data.enq (mem_req_wr_data);
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
function Action fa_write_rsp;
|
||||
action
|
||||
let wr_resp <- pop_o (master_xactor.o_wr_resp);
|
||||
let wr_resp <- pop_o (master_xactor.o_wr_resp);
|
||||
|
||||
if (wr_resp.bresp != axi4_resp_okay) begin
|
||||
$display ("ERROR: rl_discard_write_rsp: fabric response error");
|
||||
$display (" ", fshow (wr_resp));
|
||||
end
|
||||
if (wr_resp.bresp != axi4_resp_okay) begin
|
||||
$display ("ERROR: rl_discard_write_rsp: fabric response error");
|
||||
$display (" ", fshow (wr_resp));
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -150,50 +150,50 @@ module mkTest_PLIC (Empty);
|
||||
|
||||
function Action fa_print_plic_eips ();
|
||||
action
|
||||
$write ("PLIC.v_target eip =");
|
||||
$write (" ", fshow (plic.v_targets [0].m_eip));
|
||||
$write (" ", fshow (plic.v_targets [1].m_eip));
|
||||
$display ("");
|
||||
$write ("PLIC.v_target eip =");
|
||||
$write (" ", fshow (plic.v_targets [0].m_eip));
|
||||
$write (" ", fshow (plic.v_targets [1].m_eip));
|
||||
$display ("");
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
function Stmt fstmt_set_source_priority (Integer src, Priority prio);
|
||||
return seq
|
||||
fa_write_req (src * 4, zeroExtend (prio));
|
||||
fa_write_rsp;
|
||||
endseq;
|
||||
fa_write_req (src * 4, zeroExtend (prio));
|
||||
fa_write_rsp;
|
||||
endseq;
|
||||
endfunction
|
||||
|
||||
function Stmt fstmt_set_target_ies (Integer target, Bit #(32) ies);
|
||||
return seq
|
||||
fa_write_req ('h2000 + (target * 'h80), zeroExtend (ies));
|
||||
fa_write_rsp;
|
||||
endseq;
|
||||
fa_write_req ('h2000 + (target * 'h80), zeroExtend (ies));
|
||||
fa_write_rsp;
|
||||
endseq;
|
||||
endfunction
|
||||
|
||||
function Stmt fstmt_set_target_threshold (Integer target, Priority threshold);
|
||||
return seq
|
||||
fa_write_req ('h20_0000 + (target * 'h1000), zeroExtend (threshold));
|
||||
fa_write_rsp;
|
||||
endseq;
|
||||
fa_write_req ('h20_0000 + (target * 'h1000), zeroExtend (threshold));
|
||||
fa_write_rsp;
|
||||
endseq;
|
||||
endfunction
|
||||
|
||||
function Stmt fstmt_claim (Integer target);
|
||||
return seq
|
||||
fa_read_req ('h20_0004 + (target * 'h1000));
|
||||
fa_read_rsp;
|
||||
action
|
||||
let x <- pop (f_read_data);
|
||||
$display ("fstmt_claim: PLIC returned %0d", x);
|
||||
endaction
|
||||
endseq;
|
||||
fa_read_req ('h20_0004 + (target * 'h1000));
|
||||
fa_read_rsp;
|
||||
action
|
||||
let x <- pop (f_read_data);
|
||||
$display ("fstmt_claim: PLIC returned %0d", x);
|
||||
endaction
|
||||
endseq;
|
||||
endfunction
|
||||
|
||||
function Stmt fstmt_complete (Integer target, Source_Id source_id);
|
||||
return seq
|
||||
fa_write_req ('h20_0004 + (target * 'h1000), zeroExtend (source_id));
|
||||
fa_write_rsp;
|
||||
endseq;
|
||||
fa_write_req ('h20_0004 + (target * 'h1000), zeroExtend (source_id));
|
||||
fa_write_rsp;
|
||||
endseq;
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
@@ -204,89 +204,89 @@ module mkTest_PLIC (Empty);
|
||||
// Drive all interrupt requests from local regs
|
||||
for (Integer j = 0; j < n_external_interrupt_sources; j = j + 1)
|
||||
rule rl_drive_irq;
|
||||
plic.v_sources [j].m_interrupt_req (vrg_irqs [j]);
|
||||
plic.v_sources [j].m_interrupt_req (vrg_irqs [j]);
|
||||
endrule
|
||||
|
||||
// ================================================================
|
||||
|
||||
Stmt init = seq
|
||||
action
|
||||
$display ("Initializing PLIC");
|
||||
plic.server_reset.request.put (?);
|
||||
endaction
|
||||
action
|
||||
let rsp <- plic.server_reset.response.get;
|
||||
plic.set_addr_map (zeroExtend (soc_map.m_plic_addr_base),
|
||||
zeroExtend (soc_map.m_plic_addr_lim));
|
||||
endaction
|
||||
fstmt_set_source_priority (1, 0);
|
||||
fstmt_set_source_priority (2, 0);
|
||||
fstmt_set_source_priority (3, 0);
|
||||
fstmt_set_source_priority (4, 0);
|
||||
action
|
||||
$display ("Initializing PLIC");
|
||||
plic.server_reset.request.put (?);
|
||||
endaction
|
||||
action
|
||||
let rsp <- plic.server_reset.response.get;
|
||||
plic.set_addr_map (zeroExtend (soc_map.m_plic_addr_base),
|
||||
zeroExtend (soc_map.m_plic_addr_lim));
|
||||
endaction
|
||||
fstmt_set_source_priority (1, 0);
|
||||
fstmt_set_source_priority (2, 0);
|
||||
fstmt_set_source_priority (3, 0);
|
||||
fstmt_set_source_priority (4, 0);
|
||||
|
||||
fstmt_set_source_priority (5, 0);
|
||||
fstmt_set_source_priority (6, 0);
|
||||
fstmt_set_source_priority (7, 0);
|
||||
fstmt_set_source_priority (8, 0);
|
||||
fstmt_set_source_priority (5, 0);
|
||||
fstmt_set_source_priority (6, 0);
|
||||
fstmt_set_source_priority (7, 0);
|
||||
fstmt_set_source_priority (8, 0);
|
||||
|
||||
fstmt_set_source_priority (9, 0);
|
||||
fstmt_set_source_priority (10, 0);
|
||||
fstmt_set_source_priority (11, 0);
|
||||
fstmt_set_source_priority (12, 0);
|
||||
fstmt_set_source_priority (9, 0);
|
||||
fstmt_set_source_priority (10, 0);
|
||||
fstmt_set_source_priority (11, 0);
|
||||
fstmt_set_source_priority (12, 0);
|
||||
|
||||
fstmt_set_source_priority (13, 0);
|
||||
fstmt_set_source_priority (14, 0);
|
||||
fstmt_set_source_priority (15, 0);
|
||||
fstmt_set_source_priority (16, 0);
|
||||
fstmt_set_source_priority (13, 0);
|
||||
fstmt_set_source_priority (14, 0);
|
||||
fstmt_set_source_priority (15, 0);
|
||||
fstmt_set_source_priority (16, 0);
|
||||
|
||||
fstmt_set_target_ies (target_0, 0);
|
||||
fstmt_set_target_ies (target_1, 0);
|
||||
fstmt_set_target_ies (target_0, 0);
|
||||
fstmt_set_target_ies (target_1, 0);
|
||||
|
||||
fstmt_set_target_threshold (target_0, 7);
|
||||
fstmt_set_target_threshold (target_1, 7);
|
||||
delay (5);
|
||||
$display ("Finished Initializing PLIC");
|
||||
endseq;
|
||||
fstmt_set_target_threshold (target_0, 7);
|
||||
fstmt_set_target_threshold (target_1, 7);
|
||||
delay (5);
|
||||
$display ("Finished Initializing PLIC");
|
||||
endseq;
|
||||
|
||||
Stmt test1 = seq
|
||||
$display (">---------------- TEST 1");
|
||||
plic.set_verbosity (1);
|
||||
fstmt_set_source_priority (5, 4);
|
||||
$display (">---------------- TEST 1");
|
||||
plic.set_verbosity (1);
|
||||
fstmt_set_source_priority (5, 4);
|
||||
|
||||
fstmt_set_target_ies (target_0, 'b10_0000); // bit 5
|
||||
fstmt_set_target_threshold (target_0, 4);
|
||||
fstmt_set_target_ies (target_0, 'b10_0000); // bit 5
|
||||
fstmt_set_target_threshold (target_0, 4);
|
||||
|
||||
fstmt_set_target_ies (target_1, 'b10_0000); // bit 5
|
||||
fstmt_set_target_threshold (target_1, 2);
|
||||
fstmt_set_target_ies (target_1, 'b10_0000); // bit 5
|
||||
fstmt_set_target_threshold (target_1, 2);
|
||||
|
||||
plic.show_PLIC_state;
|
||||
fa_print_plic_eips;
|
||||
plic.show_PLIC_state;
|
||||
fa_print_plic_eips;
|
||||
|
||||
vrg_irqs [5] <= True;
|
||||
delay (2);
|
||||
plic.show_PLIC_state;
|
||||
fa_print_plic_eips;
|
||||
vrg_irqs [5] <= True;
|
||||
delay (2);
|
||||
plic.show_PLIC_state;
|
||||
fa_print_plic_eips;
|
||||
|
||||
fstmt_set_target_threshold (target_0, 3);
|
||||
plic.show_PLIC_state;
|
||||
fa_print_plic_eips;
|
||||
fstmt_set_target_threshold (target_0, 3);
|
||||
plic.show_PLIC_state;
|
||||
fa_print_plic_eips;
|
||||
|
||||
fstmt_claim (target_1);
|
||||
plic.show_PLIC_state;
|
||||
fa_print_plic_eips;
|
||||
fstmt_claim (target_1);
|
||||
plic.show_PLIC_state;
|
||||
fa_print_plic_eips;
|
||||
|
||||
fstmt_complete (target_1, 5);
|
||||
plic.show_PLIC_state;
|
||||
fa_print_plic_eips;
|
||||
endseq;
|
||||
fstmt_complete (target_1, 5);
|
||||
plic.show_PLIC_state;
|
||||
fa_print_plic_eips;
|
||||
endseq;
|
||||
|
||||
// ================================================================
|
||||
|
||||
mkAutoFSM (seq
|
||||
init;
|
||||
test1;
|
||||
$finish (0);
|
||||
endseq);
|
||||
init;
|
||||
test1;
|
||||
$finish (0);
|
||||
endseq);
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -8,146 +8,146 @@ copyfiles: copy_RV64_OOO_files copy_procs_lib_files copy_coherence_src_files
|
||||
PROCS_RV64G_OOO = procs/RV64G_OOO
|
||||
.PHONY: copy_RV64_OOO_files
|
||||
copy_RV64_OOO_files:
|
||||
mkdir -p $(PROCS_RV64G_OOO)
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/AluExePipeline.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/CommitStage.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/FetchStage.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/FpuMulDivExePipeline.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/MemExePipeline.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/ProcConfig.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/RenameStage.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/ReorderBufferSynth.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/ReservationStationAlu.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/ReservationStationFpuMulDiv.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/ReservationStationMem.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/RFileSynth.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/ScoreboardSynth.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/SynthParam.bsv ./$(PROCS_RV64G_OOO)/
|
||||
mkdir -p $(PROCS_RV64G_OOO)
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/AluExePipeline.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/CommitStage.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/FetchStage.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/FpuMulDivExePipeline.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/MemExePipeline.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/ProcConfig.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/RenameStage.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/ReorderBufferSynth.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/ReservationStationAlu.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/ReservationStationFpuMulDiv.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/ReservationStationMem.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/RFileSynth.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/ScoreboardSynth.bsv ./$(PROCS_RV64G_OOO)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_RV64G_OOO)/SynthParam.bsv ./$(PROCS_RV64G_OOO)/
|
||||
|
||||
PROCS_LIB = procs/lib
|
||||
.PHONY: copy_procs_lib_files
|
||||
copy_procs_lib_files:
|
||||
mkdir -p $(PROCS_LIB)
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Amo.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Bht.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/BrPred.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Btb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Bypass.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/CacheUtils.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/ConcatReg.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Decode.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/DirPredictor.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/DTlb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Ehr.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/EpochManager.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Exec.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Fifo.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Fpu.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/FullAssocTlb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/GlobalBrHistReg.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/GlobalSpecUpdate.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/GSelectPred.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/GSharePred.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/HasSpecBits.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/ITlb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/L1CoCache.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/L1LLConnect.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/L2SetAssocTlb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/L2Tlb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/LatencyTimer.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/LLCache.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/LLCDmaConnect.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/LLCRqMshrSecureModel.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MemLoader.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MemLoaderIF.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MemoryTypes.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MMIOAddrs.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MMIOCore.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MMIOInst.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MsgFifo.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MulDiv.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Performance.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/PhysRFile.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/ProcTypes.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Ras.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/RenameDebugIF.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/RenamingTable.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/ReorderBuffer.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/ReservationStationEhr.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/SafeCounter.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Scoreboard.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/SetAssocTlb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/SpecFifo.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/SpecPoisonFifo.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/SpecTagManager.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/SplitLSQ.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/StoreBuffer.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/TlbConnect.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/TlbTypes.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/TourPred.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/TourPredSecure.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/TranslationCache.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Types.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/VerificationPacket.bsv ./$(PROCS_LIB)/
|
||||
mkdir -p $(PROCS_LIB)
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Amo.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Bht.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/BrPred.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Btb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Bypass.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/CacheUtils.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/ConcatReg.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Decode.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/DirPredictor.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/DTlb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Ehr.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/EpochManager.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Exec.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Fifo.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Fpu.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/FullAssocTlb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/GlobalBrHistReg.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/GlobalSpecUpdate.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/GSelectPred.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/GSharePred.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/HasSpecBits.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/ITlb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/L1CoCache.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/L1LLConnect.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/L2SetAssocTlb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/L2Tlb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/LatencyTimer.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/LLCache.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/LLCDmaConnect.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/LLCRqMshrSecureModel.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MemLoader.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MemLoaderIF.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MemoryTypes.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MMIOAddrs.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MMIOCore.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MMIOInst.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MsgFifo.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/MulDiv.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Performance.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/PhysRFile.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/ProcTypes.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Ras.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/RenameDebugIF.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/RenamingTable.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/ReorderBuffer.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/ReservationStationEhr.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/SafeCounter.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Scoreboard.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/SetAssocTlb.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/SpecFifo.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/SpecPoisonFifo.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/SpecTagManager.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/SplitLSQ.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/StoreBuffer.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/TlbConnect.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/TlbTypes.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/TourPred.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/TourPredSecure.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/TranslationCache.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/Types.bsv ./$(PROCS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(PROCS_LIB)/VerificationPacket.bsv ./$(PROCS_LIB)/
|
||||
|
||||
COHERENCE_SRC = coherence/src
|
||||
.PHONY: copy_coherence_src_files
|
||||
copy_coherence_src_files:
|
||||
mkdir -p $(COHERENCE_SRC)
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/CCPipe.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/CCTypes.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/CrossBar.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/IBank.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/ICRqMshr.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/IPRqMshr.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/L1Bank.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/L1CRqMshr.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/L1Pipe.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/L1PRqMshr.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/LLBank.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/LLCRqMshr.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/LLPipe.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/MshrDeadlockChecker.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/RandomReplace.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/RWBramCore.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/SelfInvIBank.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/SelfInvIPipe.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/SelfInvL1Bank.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/SelfInvL1Pipe.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/SelfInvLLBank.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/SelfInvLLPipe.bsv ./$(COHERENCE_SRC)/
|
||||
mkdir -p $(COHERENCE_SRC)
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/CCPipe.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/CCTypes.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/CrossBar.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/IBank.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/ICRqMshr.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/IPRqMshr.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/L1Bank.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/L1CRqMshr.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/L1Pipe.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/L1PRqMshr.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/LLBank.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/LLCRqMshr.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/LLPipe.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/MshrDeadlockChecker.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/RandomReplace.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/RWBramCore.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/SelfInvIBank.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/SelfInvIPipe.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/SelfInvL1Bank.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/SelfInvL1Pipe.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/SelfInvLLBank.bsv ./$(COHERENCE_SRC)/
|
||||
cp -p $(RISCY_HOME)/$(COHERENCE_SRC)/SelfInvLLPipe.bsv ./$(COHERENCE_SRC)/
|
||||
|
||||
FPGAUTILS_LIB = fpgautils/lib
|
||||
FPGAUTILS_XILINX_FPU = fpgautils/xilinx/fpu
|
||||
FPGAUTILS_XILINX_RESET_REGS = fpgautils/xilinx/reset_regs
|
||||
.PHONY: copy_fpgautils_files
|
||||
copy_fpgautils_files:
|
||||
mkdir -p $(FPGAUTILS_LIB)
|
||||
mkdir -p $(FPGAUTILS_XILINX_FPU)
|
||||
mkdir -p $(FPGAUTILS_XILINX_RESET_REGS)
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/DramCommon.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/ResetGuard.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/SyncFifo.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/XilinxFpu.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/XilinxIntDiv.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/XilinxIntMul.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/XilinxSyncFifo.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/WaitAutoReset.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_XILINX_FPU)/fp_sqrt_sim.v ./$(FPGAUTILS_XILINX_FPU)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_XILINX_FPU)/fp_fma_sim.v ./$(FPGAUTILS_XILINX_FPU)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_XILINX_FPU)/fp_div_sim.v ./$(FPGAUTILS_XILINX_FPU)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_XILINX_RESET_REGS)/reset_guard.v ./$(FPGAUTILS_XILINX_RESET_REGS)/
|
||||
mkdir -p $(FPGAUTILS_LIB)
|
||||
mkdir -p $(FPGAUTILS_XILINX_FPU)
|
||||
mkdir -p $(FPGAUTILS_XILINX_RESET_REGS)
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/DramCommon.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/ResetGuard.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/SyncFifo.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/XilinxFpu.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/XilinxIntDiv.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/XilinxIntMul.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/XilinxSyncFifo.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_LIB)/WaitAutoReset.bsv ./$(FPGAUTILS_LIB)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_XILINX_FPU)/fp_sqrt_sim.v ./$(FPGAUTILS_XILINX_FPU)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_XILINX_FPU)/fp_fma_sim.v ./$(FPGAUTILS_XILINX_FPU)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_XILINX_FPU)/fp_div_sim.v ./$(FPGAUTILS_XILINX_FPU)/
|
||||
cp -p $(RISCY_HOME)/$(FPGAUTILS_XILINX_RESET_REGS)/reset_guard.v ./$(FPGAUTILS_XILINX_RESET_REGS)/
|
||||
|
||||
CONNECTAL_BSV = connectal/bsv
|
||||
CONNECTAL_LIB_BSV = connectal/lib/bsv
|
||||
CONNECTAL_TESTS_SPI = connectal/tests/spi
|
||||
.PHONY: copy_connectal_files
|
||||
copy_connectal_files:
|
||||
mkdir -p $(CONNECTAL_BSV)
|
||||
mkdir -p $(CONNECTAL_LIB_BSV)
|
||||
mkdir -p $(CONNECTAL_TESTS_SPI)
|
||||
cp -p $(RISCY_HOME)/$(CONNECTAL_BSV)/ConnectalBramFifo.bsv ./$(CONNECTAL_BSV)/
|
||||
cp -p $(RISCY_HOME)/$(CONNECTAL_BSV)/ConnectalClocks.bsv ./$(CONNECTAL_BSV)/
|
||||
cp -p $(RISCY_HOME)/$(CONNECTAL_LIB_BSV)/Arith.bsv ./$(CONNECTAL_LIB_BSV)/
|
||||
cp -p $(RISCY_HOME)/$(CONNECTAL_TESTS_SPI)/ConnectalProjectConfig.bsv ./$(CONNECTAL_TESTS_SPI)/
|
||||
tree .
|
||||
mkdir -p $(CONNECTAL_BSV)
|
||||
mkdir -p $(CONNECTAL_LIB_BSV)
|
||||
mkdir -p $(CONNECTAL_TESTS_SPI)
|
||||
cp -p $(RISCY_HOME)/$(CONNECTAL_BSV)/ConnectalBramFifo.bsv ./$(CONNECTAL_BSV)/
|
||||
cp -p $(RISCY_HOME)/$(CONNECTAL_BSV)/ConnectalClocks.bsv ./$(CONNECTAL_BSV)/
|
||||
cp -p $(RISCY_HOME)/$(CONNECTAL_LIB_BSV)/Arith.bsv ./$(CONNECTAL_LIB_BSV)/
|
||||
cp -p $(RISCY_HOME)/$(CONNECTAL_TESTS_SPI)/ConnectalProjectConfig.bsv ./$(CONNECTAL_TESTS_SPI)/
|
||||
tree .
|
||||
|
||||
@@ -118,7 +118,7 @@ module mkXBar#(
|
||||
for(Integer i = 0; i < valueOf(srcNum); i = i+1) begin
|
||||
if(isDeqSrc(fromInteger(i))) begin
|
||||
propDstIdx[i][1] <= Invalid;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t XBar %m: deq src %d", $time, i);
|
||||
doAssert(isValid(propDstIdx[i][1]), "src must be proposing");
|
||||
end
|
||||
@@ -133,7 +133,7 @@ module mkXBar#(
|
||||
rule doEnq(enqDst[i][1] matches tagged Valid .d);
|
||||
dstIfc[i].put(d);
|
||||
enqDst[i][1] <= Invalid; // reset enq command
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t XBAR %m: enq dst %d ; ", $time, i, fshow(d));
|
||||
endrule
|
||||
end
|
||||
|
||||
@@ -545,7 +545,7 @@ module mkIBank#(
|
||||
doAssert(isValid(cRqEOC), "cRq hit on another cRq, cRqEOC must be true");
|
||||
cRqMshr.pipelineResp.setSucc(fromMaybe(?, cRqEOC), Valid (n));
|
||||
cRqSetDepNoCacheChange;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: cRq: own by other cRq ", $time,
|
||||
fshow(cOwner), ", depend on cRq ", fshow(cRqEOC)
|
||||
);
|
||||
@@ -557,7 +557,7 @@ module mkIBank#(
|
||||
"cRq swapped in by previous cRq, tag must match & cs = S"
|
||||
);
|
||||
// Hit
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: cRq: own by itself, hit", $time);
|
||||
cRqHit(n, procRq);
|
||||
end
|
||||
@@ -566,7 +566,7 @@ module mkIBank#(
|
||||
// cache has no owner, cRq must just go through tag match
|
||||
// check for cRqEOC to append to dependency chain
|
||||
if(cRqEOC matches tagged Valid .k) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: cRq: no owner, depend on cRq ", $time, fshow(k));
|
||||
cRqMshr.pipelineResp.setSucc(k, Valid (n));
|
||||
cRqSetDepNoCacheChange;
|
||||
@@ -574,18 +574,18 @@ module mkIBank#(
|
||||
else if(ram.info.cs == I || ram.info.tag == getTag(procRq.addr)) begin
|
||||
// No Replacement necessary
|
||||
if(ram.info.cs > I) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: cRq: no owner, hit", $time);
|
||||
cRqHit(n, procRq);
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: cRq: no owner, miss no replace", $time);
|
||||
cRqMissNoReplacement;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: cRq: no owner, replace", $time);
|
||||
cRqReplacement;
|
||||
end
|
||||
@@ -627,14 +627,14 @@ module mkIBank#(
|
||||
// pRq is always directly handled: either dropped or Done
|
||||
|
||||
if(pipeOut.pRqMiss) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: pRq: drop", $time);
|
||||
// pRq can be directly dropped, no successor (since just go through pipeline)
|
||||
pRqMshr.pipelineResp.releaseEntry(n);
|
||||
pipeline.deqWrite(Invalid, pipeOut.ram, False);
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: pRq: valid process", $time);
|
||||
// should process pRq
|
||||
doAssert(ram.info.cs == S && pRq.toState == I && ram.info.tag == getTag(pRq.addr),
|
||||
@@ -677,13 +677,13 @@ module mkIBank#(
|
||||
// flush always goes through cache pipeline, and is directly handled
|
||||
// here: either dropped or Done
|
||||
if(ram.info.cs == I) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: flush: drop", $time);
|
||||
// flush can be directly dropped
|
||||
pRqMshr.pipelineResp.releaseEntry(n);
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: flush: valid process", $time);
|
||||
pRqMshr.pipelineResp.setDone(n);
|
||||
rsToPIndexQ.enq(PRq (n));
|
||||
@@ -751,7 +751,7 @@ module mkIBank#(
|
||||
);
|
||||
cRqIndexQ.deq;
|
||||
cRqMshr.sendRsToC.releaseEntry(cRqIndexQ.first); // release MSHR entry
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m sendRsToC: ", $time,
|
||||
fshow(cRqIndexQ.first), " ; ",
|
||||
fshow(inst)
|
||||
|
||||
@@ -210,7 +210,7 @@ module mkICRqMshrSafe#(
|
||||
initIdx <= initIdx + 1;
|
||||
if(initIdx == fromInteger(valueOf(cRqNum) - 1)) begin
|
||||
inited <= True;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t ICRqMshrSafe %m: init empty entry done", $time);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -116,7 +116,7 @@ module mkIPRqMshrSafe(
|
||||
initIdx <= initIdx + 1;
|
||||
if(initIdx == fromInteger(valueOf(pRqNum) - 1)) begin
|
||||
inited <= True;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t IPRqMshrSafe %m: init empty entry done", $time);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -520,7 +520,7 @@ module mkL1Bank#(
|
||||
},
|
||||
line: newLine // write new data into cache
|
||||
}, True); // hit, so update rep info
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: Hit func: update ram: ", $time,
|
||||
fshow(newLine), " ; ",
|
||||
fshow(succ)
|
||||
@@ -534,7 +534,7 @@ module mkL1Bank#(
|
||||
req: req,
|
||||
succ: succ
|
||||
});
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: Hit func: AMO process in next cycle", $time);
|
||||
end
|
||||
endaction
|
||||
@@ -618,7 +618,7 @@ module mkL1Bank#(
|
||||
end
|
||||
// release MSHR entry
|
||||
cRqMshr.pipelineResp.releaseEntry(n);
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: Sc early fail func: ", $time,
|
||||
fshow(resetOwner), " ; ",
|
||||
fshow(succ)
|
||||
@@ -722,7 +722,7 @@ module mkL1Bank#(
|
||||
doAssert(isValid(cRqEOC), ("cRq hit on another cRq, cRqEOC must be true"));
|
||||
cRqMshr.pipelineResp.setSucc(fromMaybe(?, cRqEOC), Valid (n));
|
||||
cRqSetDepNoCacheChange;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: own by other cRq ", $time,
|
||||
fshow(cOwner), ", depend on cRq ", fshow(cRqEOC)
|
||||
);
|
||||
@@ -736,7 +736,7 @@ module mkL1Bank#(
|
||||
);
|
||||
// Hit or Miss (but no replacement)
|
||||
if(enough_cs) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: own by itself, hit", $time);
|
||||
cRqHit(n, procRq);
|
||||
end
|
||||
@@ -744,14 +744,14 @@ module mkL1Bank#(
|
||||
// Sc already fails, so we don't need to req parent. Since
|
||||
// Sc is the owner of the line, we need to reset owner to
|
||||
// Invalid.
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: own by itself, Sc early fails, ",
|
||||
$time, fshow(linkAddr)
|
||||
);
|
||||
cRqScEarlyFail(True);
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: own by itself, miss no replace", $time);
|
||||
cRqMissNoReplacement;
|
||||
end
|
||||
@@ -767,7 +767,7 @@ module mkL1Bank#(
|
||||
// check for cRqEOC to append to dependency chain
|
||||
// Only append to dep-chain if is in Init state
|
||||
if(cRqEOC matches tagged Valid .k &&& cState == Init) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: no owner, depend on cRq, ", $time,
|
||||
fshow(cState), " ; ", fshow(cRqEOC)
|
||||
);
|
||||
@@ -779,7 +779,7 @@ module mkL1Bank#(
|
||||
if(tag_match && enough_cs) begin
|
||||
// Hit
|
||||
doAssert(cs_valid, "hit, so cs must > I");
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: no owner, hit", $time);
|
||||
cRqHit(n, procRq);
|
||||
end
|
||||
@@ -787,7 +787,7 @@ module mkL1Bank#(
|
||||
// Sc already fails, so we don't need to req parent. Since
|
||||
// there is no owner of the line, we can reset owner to
|
||||
// Invalid.
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: no owner, Sc early fails, ",
|
||||
$time, fshow(linkAddr)
|
||||
);
|
||||
@@ -795,12 +795,12 @@ module mkL1Bank#(
|
||||
end
|
||||
else if(cs_valid && !tag_match) begin
|
||||
// Req parent, need replacement
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: no owner, replace", $time);
|
||||
cRqReplacement;
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: no owner, miss no replace", $time);
|
||||
// Req parent, no replacement needed
|
||||
cRqMissNoReplacement;
|
||||
@@ -841,7 +841,7 @@ module mkL1Bank#(
|
||||
// and pRq is always directly handled: either dropped or Done
|
||||
|
||||
if(pipeOut.pRqMiss || ram.info.cs <= pRq.toState || ram.info.tag != getTag(pRq.addr)) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: pRq: drop", $time);
|
||||
// pRq can be directly dropped
|
||||
// must go through tag match, no successor
|
||||
@@ -859,7 +859,7 @@ module mkL1Bank#(
|
||||
// must be the case the pRq overtakes cRq
|
||||
L1CRqState cState = pipeOutCState;
|
||||
cRqSlotT cSlot = pipeOutCSlot;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: pRq: overtake cRq: ", $time,
|
||||
fshow(cOwner), " ; ",
|
||||
fshow(cRq), " ; ",
|
||||
@@ -891,7 +891,7 @@ module mkL1Bank#(
|
||||
});
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: pRq: valid process", $time);
|
||||
// line must NOT be owned
|
||||
doAssert(ram.info.owner == Invalid,
|
||||
@@ -937,13 +937,13 @@ module mkL1Bank#(
|
||||
// flush always goes through cache pipeline, and is directly handled
|
||||
// here: either dropped or Done
|
||||
if(ram.info.cs == I) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: flush: drop", $time);
|
||||
// flush can be directly dropped
|
||||
pRqMshr.pipelineResp.releaseEntry(n);
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: flush: valid process", $time);
|
||||
pRqMshr.pipelineResp.setDone_setData(n, ram.info.cs == M ? Valid (ram.line) : Invalid);
|
||||
rsToPIndexQ.enq(PRq (n));
|
||||
|
||||
@@ -220,7 +220,7 @@ module mkL1CRqMshrSafe#(
|
||||
initIdx <= initIdx + 1;
|
||||
if(initIdx == fromInteger(valueOf(cRqNum) - 1)) begin
|
||||
inited <= True;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1CRqMshrSafe %m: init empty entry done", $time);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -124,7 +124,7 @@ module mkL1PRqMshrSafe(
|
||||
initIdx <= initIdx + 1;
|
||||
if(initIdx == fromInteger(valueOf(pRqNum) - 1)) begin
|
||||
inited <= True;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1PRqMshrSafe %m: init empty entry done", $time);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -230,7 +230,7 @@ module mkL1Pipe(
|
||||
return actionvalue
|
||||
function tagT getTag(Addr a) = truncateLSB(a);
|
||||
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m tagMatch: ", $time,
|
||||
fshow(cmd), " ; ",
|
||||
fshow(getTag(getAddrFromCmd(cmd))),
|
||||
|
||||
@@ -555,7 +555,7 @@ module mkLLBank#(
|
||||
});
|
||||
toMQ.enq(msg);
|
||||
toMInfoQ.deq; // deq info
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m sendToM: load only: ", $time, fshow(msg));
|
||||
doAssert(!isValid(data), "cannot have data");
|
||||
doAssert(!doLdAfterReplace, "doLdAfterReplace should be false");
|
||||
@@ -580,7 +580,7 @@ module mkLLBank#(
|
||||
toMInfoQ.deq; // deq info
|
||||
// dma write can be resp (i.e. mshr entry can be released)
|
||||
rsStToDmaIndexQ_sendToM.enq(n);
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m sendToM: dma write: ", $time, fshow(msg));
|
||||
doAssert(isRqFromDma(cRq.id), "must be dma write");
|
||||
doAssert(isValid(data), "dma write must have data");
|
||||
@@ -604,7 +604,7 @@ module mkLLBank#(
|
||||
// whole thing is done, reset bit and deq info
|
||||
toMInfoQ.deq;
|
||||
doLdAfterReplace <= False;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m sendToM: rep then ld: ld: ", $time, fshow(msg));
|
||||
`ifdef PERF_COUNT
|
||||
// performance counter: start miss timer
|
||||
@@ -620,7 +620,7 @@ module mkLLBank#(
|
||||
toMQ.enq(msg);
|
||||
// don't deq info, do ld next time
|
||||
doLdAfterReplace <= True;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m sendToM: rep then ld: rep: ", $time, fshow(msg));
|
||||
end
|
||||
doAssert(isRqFromC(cRq.id), "must be child req");
|
||||
@@ -1168,7 +1168,7 @@ module mkLLBank#(
|
||||
// add to same addr dependency
|
||||
cRqMshr.pipelineResp.setAddrSucc(m, Valid (n));
|
||||
cRqSetDepNoCacheChange;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRq: own by other cRq, same addr dep: ", $time,
|
||||
fshow(cOwner), " ; ", fshow(cRqEOC)
|
||||
);
|
||||
@@ -1178,7 +1178,7 @@ module mkLLBank#(
|
||||
// add to rep dependency
|
||||
cRqMshr.pipelineResp.setRepSucc(cOwner.mshrIdx, Valid (n));
|
||||
cRqSetDepNoCacheChange;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRq: own by other cRq, rep dep: ", $time,
|
||||
fshow(cOwner)
|
||||
);
|
||||
@@ -1200,12 +1200,12 @@ module mkLLBank#(
|
||||
// req from child, get dir pend
|
||||
Vector#(childNum, DirPend) dirPend = getDirPendNonCompatForChild;
|
||||
if(dirPend == replicate(Invalid)) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRq from child: own by itself, hit", $time);
|
||||
cRqFromCHit(n, cRq, False);
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRq from child: own by itself, miss no replace: ", $time,
|
||||
fshow(dirPend)
|
||||
);
|
||||
@@ -1216,12 +1216,12 @@ module mkLLBank#(
|
||||
// req from DMA, get dir pend
|
||||
Vector#(childNum, DirPend) dirPend = getDirPendNonCompatForDma;
|
||||
if(dirPend == replicate(Invalid)) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRq from dma: own by itself, hit", $time);
|
||||
cRqFromDmaHit(n, cRq);
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRq from dma: own by itself, miss by children: ", $time);
|
||||
cRqFromDmaMissByChildren(dirPend);
|
||||
end
|
||||
@@ -1237,7 +1237,7 @@ module mkLLBank#(
|
||||
|
||||
// only check for cRqEOC to append to dependency chain when firt time go through tag match
|
||||
if(cRqEOC matches tagged Valid .m &&& cState == Init) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRq: no owner, depend on cRq ", $time,
|
||||
fshow(cState), " ; ",
|
||||
fshow(cRqEOC)
|
||||
@@ -1253,12 +1253,12 @@ module mkLLBank#(
|
||||
// No Replacement necessary, check dir
|
||||
Vector#(childNum, DirPend) dirPend = getDirPendNonCompatForChild;
|
||||
if(ram.info.cs > I && dirPend == replicate(Invalid)) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRq: no owner, hit", $time);
|
||||
cRqFromCHit(n, cRq, False);
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRq: no owner, miss no replace: ", $time,
|
||||
fshow(dirPend)
|
||||
);
|
||||
@@ -1268,7 +1268,7 @@ module mkLLBank#(
|
||||
else begin
|
||||
// need replacement, check dir
|
||||
Vector#(childNum, DirPend) dirPend = getDirPendNonI;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRq: no owner, replace: ", $time,
|
||||
fshow(dirPend)
|
||||
);
|
||||
@@ -1289,7 +1289,7 @@ module mkLLBank#(
|
||||
end
|
||||
else begin
|
||||
// miss in LLC, so req mem and req is done!
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRq from dma: no owner, miss req mem", $time);
|
||||
toMInfoQ.enq(ToMemInfo {
|
||||
mshrIdx: n,
|
||||
@@ -1355,7 +1355,7 @@ module mkLLBank#(
|
||||
cRqT cRq = pipeOutCRq;
|
||||
cRqSlotT cSlot = pipeOutCSlot;
|
||||
LLCRqState cState = pipeOutCState;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRs: match cRq: ", $time,
|
||||
fshow(cOwner), " ; ",
|
||||
fshow(cRq), " ; ",
|
||||
@@ -1380,7 +1380,7 @@ module mkLLBank#(
|
||||
// replacement done, evict line
|
||||
Maybe#(cRqIndexT) repSucc = pipeOutRepSucc;
|
||||
cRqFromCEvict(cOwner.mshrIdx, cRq, repSucc);
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRs: match cRq: replace done: ", $time,
|
||||
fshow(repSucc)
|
||||
);
|
||||
@@ -1394,7 +1394,7 @@ module mkLLBank#(
|
||||
waitP: cSlot.waitP,
|
||||
dirPend: newDirPend
|
||||
});
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRs: match cRq: replace not done: ", $time,
|
||||
fshow(newDirPend)
|
||||
);
|
||||
@@ -1419,7 +1419,7 @@ module mkLLBank#(
|
||||
end
|
||||
end
|
||||
endcase
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRs: match cRq: cRq in WaitSt: ", $time,
|
||||
fshow(newDirPend)
|
||||
);
|
||||
@@ -1446,7 +1446,7 @@ module mkLLBank#(
|
||||
end
|
||||
else begin
|
||||
// does not match any cRq, so just deq pipe & write ram
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m pipelineResp: cRs: no owner: ", $time);
|
||||
pipeline.deqWrite(Invalid, ram, False);
|
||||
end
|
||||
|
||||
@@ -250,7 +250,7 @@ module mkLLCRqMshr#(
|
||||
initIdx <= initIdx + 1;
|
||||
if(initIdx == fromInteger(valueOf(cRqNum) - 1)) begin
|
||||
inited <= True;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LLCRqMshrSafe %m: init empty entry done", $time);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -202,7 +202,7 @@ module mkLLPipe(
|
||||
return actionvalue
|
||||
function tagT getTag(Addr a) = truncateLSB(a);
|
||||
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m tagMatch: ", $time,
|
||||
fshow(cmd), " ; ",
|
||||
fshow(getTag(getAddrFromCmd(cmd))), " ; ",
|
||||
|
||||
@@ -408,7 +408,7 @@ module mkSelfInvIBank#(
|
||||
doAssert(isValid(cRqEOC), "cRq hit on another cRq, cRqEOC must be true");
|
||||
cRqMshr.pipelineResp.setSucc(fromMaybe(?, cRqEOC), Valid (n));
|
||||
cRqSetDepNoCacheChange;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: cRq: own by other cRq ", $time,
|
||||
fshow(cOwner), ", depend on cRq ", fshow(cRqEOC)
|
||||
);
|
||||
@@ -421,7 +421,7 @@ module mkSelfInvIBank#(
|
||||
"cRq swapped in by previous cRq, tag must match & cs = S"
|
||||
);
|
||||
// Hit
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: cRq: own by itself, hit", $time);
|
||||
cRqHit(n, procRq);
|
||||
end
|
||||
@@ -430,19 +430,19 @@ module mkSelfInvIBank#(
|
||||
// cache has no owner, cRq must just go through tag match
|
||||
// check for cRqEOC to append to dependency chain
|
||||
if(cRqEOC matches tagged Valid .k) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: cRq: no owner, depend on cRq ", $time, fshow(k));
|
||||
cRqMshr.pipelineResp.setSucc(k, Valid (n));
|
||||
cRqSetDepNoCacheChange;
|
||||
end
|
||||
else if(ram.info.cs > I && ram.info.tag == getTag(procRq.addr)) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: cRq: no owner, hit", $time);
|
||||
cRqHit(n, procRq);
|
||||
end
|
||||
else begin
|
||||
// can always sliently replace
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m pipelineResp: cRq: no owner, miss no replace", $time);
|
||||
cRqMissNoReplacement;
|
||||
end
|
||||
@@ -515,7 +515,7 @@ module mkSelfInvIBank#(
|
||||
);
|
||||
cRqIndexQ.deq;
|
||||
cRqMshr.sendRsToC.releaseEntry(cRqIndexQ.first); // release MSHR entry
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t I %m sendRsToC: ", $time,
|
||||
fshow(cRqIndexQ.first), " ; ",
|
||||
fshow(inst)
|
||||
|
||||
@@ -524,7 +524,7 @@ module mkSelfInvL1Bank#(
|
||||
},
|
||||
line: newLine // write new data into cache
|
||||
}, True); // hit, so update rep info
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: Hit func: update ram: ", $time,
|
||||
fshow(newLine), " ; ",
|
||||
fshow(succ), " ; ",
|
||||
@@ -545,7 +545,7 @@ module mkSelfInvL1Bank#(
|
||||
req: req,
|
||||
succ: succ
|
||||
});
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: Hit func: AMO process in next cycle", $time);
|
||||
end
|
||||
endaction
|
||||
@@ -630,7 +630,7 @@ module mkSelfInvL1Bank#(
|
||||
end
|
||||
// release MSHR entry
|
||||
cRqMshr.pipelineResp.releaseEntry(n);
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: Sc early fail func: ", $time,
|
||||
fshow(resetOwner), " ; ",
|
||||
fshow(succ)
|
||||
@@ -742,7 +742,7 @@ module mkSelfInvL1Bank#(
|
||||
doAssert(isValid(cRqEOC), ("cRq hit on another cRq, cRqEOC must be true"));
|
||||
cRqMshr.pipelineResp.setSucc(fromMaybe(?, cRqEOC), Valid (n));
|
||||
cRqSetDepNoCacheChange;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: own by other cRq ", $time,
|
||||
fshow(cOwner), ", depend on cRq ", fshow(cRqEOC)
|
||||
);
|
||||
@@ -754,7 +754,7 @@ module mkSelfInvL1Bank#(
|
||||
doAssert(tag_match, "cRq swapped in by previous cRq, tag must match");
|
||||
// Hit or Miss (but no replacement)
|
||||
if(enough_cs) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: own by itself, hit", $time);
|
||||
cRqHit(n, procRq, False);
|
||||
end
|
||||
@@ -762,14 +762,14 @@ module mkSelfInvL1Bank#(
|
||||
// Sc already fails, so we don't need to req parent. Since
|
||||
// Sc is the owner of the line, we need to reset owner to
|
||||
// Invalid.
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: own by itself, Sc early fails, ",
|
||||
$time, fshow(linkAddr)
|
||||
);
|
||||
cRqScEarlyFail(True);
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: own by itself, miss no replace", $time);
|
||||
cRqMissNoReplacement;
|
||||
end
|
||||
@@ -785,7 +785,7 @@ module mkSelfInvL1Bank#(
|
||||
// check for cRqEOC to append to dependency chain
|
||||
// Only append to dep-chain if is in Init state
|
||||
if(cRqEOC matches tagged Valid .k &&& cState == Init) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: no owner, depend on cRq ", $time,
|
||||
fshow(cState), " ; ", fshow(cRqEOC)
|
||||
);
|
||||
@@ -797,7 +797,7 @@ module mkSelfInvL1Bank#(
|
||||
if(tag_match && enough_cs) begin
|
||||
// Hit
|
||||
doAssert(cs_valid, "hit, so cs must > I");
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: no owner, hit", $time);
|
||||
cRqHit(n, procRq, False);
|
||||
end
|
||||
@@ -805,7 +805,7 @@ module mkSelfInvL1Bank#(
|
||||
// Sc already fails, so we don't need to req parent. Since
|
||||
// there is no owner of the line, we can reset owner to
|
||||
// Invalid.
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: no owner, Sc early fails, ",
|
||||
$time, fshow(linkAddr)
|
||||
);
|
||||
@@ -813,14 +813,14 @@ module mkSelfInvL1Bank#(
|
||||
end
|
||||
else if(cs_needs_evict && !tag_match) begin
|
||||
// Req parent, need replacement
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: no owner, replace", $time);
|
||||
cRqReplacement;
|
||||
end
|
||||
else begin
|
||||
// Req parent, no Replacement necessary, we can silently replace S line
|
||||
Bool silent_replace = ram.info.cs == S && !tag_match;
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: cRq: ",
|
||||
"no owner, miss no replace, silent replace ",
|
||||
$time, fshow(silent_replace));
|
||||
@@ -867,7 +867,7 @@ module mkSelfInvL1Bank#(
|
||||
doAssert(pRq.toState == S, "must downgrade to S");
|
||||
|
||||
if(pipeOut.pRqMiss || ram.info.cs <= pRq.toState || ram.info.tag != getTag(pRq.addr)) begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: pRq: drop", $time);
|
||||
// pRq can be directly dropped
|
||||
// must go through tag match, no successor
|
||||
@@ -881,7 +881,7 @@ module mkSelfInvL1Bank#(
|
||||
end
|
||||
end
|
||||
else begin
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t L1 %m pipelineResp: pRq: valid process", $time);
|
||||
// line must NOT be owned
|
||||
doAssert(ram.info.owner == Invalid,
|
||||
|
||||
@@ -201,7 +201,7 @@ module mkSelfInvLLPipe(
|
||||
return actionvalue
|
||||
function tagT getTag(Addr a) = truncateLSB(a);
|
||||
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("%t LL %m tagMatch: ", $time,
|
||||
fshow(cmd), " ; ",
|
||||
fshow(getTag(getAddrFromCmd(cmd))), " ; ",
|
||||
|
||||
@@ -96,7 +96,7 @@ endmodule
|
||||
|
||||
module mkDualClockBramFIFOF#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFOF#(t))
|
||||
provisos (Bits#(t,sizet),
|
||||
Add#(1,a__,sizet));
|
||||
Add#(1,a__,sizet));
|
||||
String fifo_size = "18Kb";
|
||||
Vector#(TDiv#(sizet,36),X7FifoSyncMacro#(36)) fifos <- replicateM(vmkBramFifo(fifo_size, srcClock, srcReset, dstClock, dstReset));
|
||||
Wire#(Bit#(1)) rdenWire <- mkDWire(0, clocked_by dstClock, reset_by dstReset);
|
||||
@@ -107,19 +107,19 @@ module mkDualClockBramFIFOF#(Clock srcClock, Reset srcReset, Clock dstClock, Res
|
||||
Reg#(Bit#(9)) rdcount <- mkReg(0, clocked_by dstClock, reset_by dstReset);
|
||||
Reg#(Bit#(9)) wrcount <- mkReg(0, clocked_by srcClock, reset_by srcReset);
|
||||
rule rdenRule;
|
||||
fifos[i].rden(rdenWire);
|
||||
fifos[i].rden(rdenWire);
|
||||
endrule
|
||||
rule wrenRule;
|
||||
fifos[i].wren(wrenWire);
|
||||
fifos[i].wren(wrenWire);
|
||||
endrule
|
||||
rule inputs;
|
||||
fifos[i].din(dinWires[i]);
|
||||
fifos[i].din(dinWires[i]);
|
||||
endrule
|
||||
rule countrds;
|
||||
rdcount <= fifos[i].rdcount();
|
||||
rdcount <= fifos[i].rdcount();
|
||||
endrule
|
||||
rule countwrs;
|
||||
wrcount <= fifos[i].wrcount();
|
||||
wrcount <= fifos[i].wrcount();
|
||||
endrule
|
||||
end
|
||||
|
||||
@@ -147,7 +147,7 @@ endmodule
|
||||
|
||||
module mkDualClockBramFIFO#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFO#(t))
|
||||
provisos (Bits#(t,sizet),
|
||||
Add#(1,a__,sizet));
|
||||
Add#(1,a__,sizet));
|
||||
|
||||
let syncFifo <- mkDualClockBramFIFOF(srcClock, srcReset, dstClock, dstReset);
|
||||
method enq = syncFifo.enq;
|
||||
@@ -158,7 +158,7 @@ endmodule
|
||||
`else // compatibility mode
|
||||
module mkDualClockBramFIFOF#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFOF#(t))
|
||||
provisos (Bits#(t,sizet),
|
||||
Add#(1,a__,sizet));
|
||||
Add#(1,a__,sizet));
|
||||
let syncFifo <- mkSyncFIFO(512, srcClock, srcReset, dstClock);
|
||||
method enq = syncFifo.enq;
|
||||
method deq = syncFifo.deq;
|
||||
@@ -168,7 +168,7 @@ module mkDualClockBramFIFOF#(Clock srcClock, Reset srcReset, Clock dstClock, Res
|
||||
endmodule
|
||||
module mkDualClockBramFIFO#(Clock srcClock, Reset srcReset, Clock dstClock, Reset dstReset)(FIFO#(t))
|
||||
provisos (Bits#(t,sizet),
|
||||
Add#(1,a__,sizet));
|
||||
Add#(1,a__,sizet));
|
||||
|
||||
let syncFifo <- mkSyncFIFO(512, srcClock, srcReset, dstClock);
|
||||
method enq = syncFifo.enq;
|
||||
|
||||
@@ -271,7 +271,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
rVal2: rVal2,
|
||||
pc: pc,
|
||||
ppc: ppc,
|
||||
orig_inst: orig_inst,
|
||||
orig_inst: orig_inst,
|
||||
spec_tag: x.spec_tag
|
||||
},
|
||||
spec_bits: dispToReg.spec_bits
|
||||
@@ -290,7 +290,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
if (verbosity > 0) begin
|
||||
$display ("AluExePipeline.doExeAlu: regToExe = ", fshow (regToExe));
|
||||
$display ("AluExePipeline.doExeAlu: exec_result = ", fshow (exec_result));
|
||||
end
|
||||
end
|
||||
|
||||
// when inst needs to store csrData in ROB, it must have iType = Csr, cannot mispredict
|
||||
if(isValid(x.dInst.csr)) begin
|
||||
@@ -342,7 +342,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
// update the instruction in the reorder buffer.
|
||||
inIfc.rob_setExecuted(
|
||||
x.tag,
|
||||
x.data,
|
||||
x.data,
|
||||
x.csrData,
|
||||
x.controlFlow
|
||||
`ifdef RVFI
|
||||
|
||||
@@ -263,49 +263,49 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
Maybe #(RET_Updates) no_ret_updates = tagged Invalid;
|
||||
|
||||
function Action fa_to_TV (Integer way,
|
||||
Bit #(64) serial_num,
|
||||
Maybe #(Tuple2 #(Bit #(12), Data)) maybe_csr_upd,
|
||||
ToReorderBuffer deq_data,
|
||||
Bit #(5) fflags,
|
||||
Data mstatus,
|
||||
Maybe #(Trap_Updates) m_trap_updates,
|
||||
Maybe #(RET_Updates) m_ret_updates);
|
||||
Bit #(64) serial_num,
|
||||
Maybe #(Tuple2 #(Bit #(12), Data)) maybe_csr_upd,
|
||||
ToReorderBuffer deq_data,
|
||||
Bit #(5) fflags,
|
||||
Data mstatus,
|
||||
Maybe #(Trap_Updates) m_trap_updates,
|
||||
Maybe #(RET_Updates) m_ret_updates);
|
||||
action
|
||||
let tval = (m_trap_updates matches tagged Valid .tu ? tu.tval : deq_data.tval);
|
||||
let upd_pc = (m_ret_updates matches tagged Valid .ru ? ru.new_pc : deq_data.pc);
|
||||
let x = Trace_Data2 {serial_num: serial_num,
|
||||
maybe_csr_upd: maybe_csr_upd,
|
||||
pc: upd_pc,
|
||||
orig_inst: deq_data.orig_inst,
|
||||
iType: deq_data.iType,
|
||||
dst: deq_data.dst,
|
||||
dst_data: deq_data.dst_data,
|
||||
store_data: deq_data.store_data,
|
||||
store_data_BE: deq_data.store_data_BE,
|
||||
csr: deq_data.csr,
|
||||
trap: deq_data.trap,
|
||||
tval: tval,
|
||||
ppc_vaddr_csrData: deq_data.ppc_vaddr_csrData,
|
||||
fflags: fflags, // deq_data.fflags only has incremental flags
|
||||
will_dirty_fpu_state: deq_data.will_dirty_fpu_state,
|
||||
mstatus: mstatus, // when SD/XS/FS have changed
|
||||
let tval = (m_trap_updates matches tagged Valid .tu ? tu.tval : deq_data.tval);
|
||||
let upd_pc = (m_ret_updates matches tagged Valid .ru ? ru.new_pc : deq_data.pc);
|
||||
let x = Trace_Data2 {serial_num: serial_num,
|
||||
maybe_csr_upd: maybe_csr_upd,
|
||||
pc: upd_pc,
|
||||
orig_inst: deq_data.orig_inst,
|
||||
iType: deq_data.iType,
|
||||
dst: deq_data.dst,
|
||||
dst_data: deq_data.dst_data,
|
||||
store_data: deq_data.store_data,
|
||||
store_data_BE: deq_data.store_data_BE,
|
||||
csr: deq_data.csr,
|
||||
trap: deq_data.trap,
|
||||
tval: tval,
|
||||
ppc_vaddr_csrData: deq_data.ppc_vaddr_csrData,
|
||||
fflags: fflags, // deq_data.fflags only has incremental flags
|
||||
will_dirty_fpu_state: deq_data.will_dirty_fpu_state,
|
||||
mstatus: mstatus, // when SD/XS/FS have changed
|
||||
|
||||
// Trap and RET updates
|
||||
prv: ( m_trap_updates matches tagged Valid .tu
|
||||
? tu.prv
|
||||
: (m_ret_updates matches tagged Valid .ru
|
||||
? ru.prv
|
||||
: ?)),
|
||||
status: ( m_trap_updates matches tagged Valid .tu
|
||||
? tu.status
|
||||
: (m_ret_updates matches tagged Valid .ru
|
||||
? ru.status
|
||||
: ?)),
|
||||
tvec: fromMaybe (?, m_trap_updates).new_pc,
|
||||
cause: fromMaybe (?, m_trap_updates).cause,
|
||||
epc: fromMaybe (?, m_trap_updates).epc
|
||||
};
|
||||
inIfc.v_to_TV [way].put (x);
|
||||
// Trap and RET updates
|
||||
prv: ( m_trap_updates matches tagged Valid .tu
|
||||
? tu.prv
|
||||
: (m_ret_updates matches tagged Valid .ru
|
||||
? ru.prv
|
||||
: ?)),
|
||||
status: ( m_trap_updates matches tagged Valid .tu
|
||||
? tu.status
|
||||
: (m_ret_updates matches tagged Valid .ru
|
||||
? ru.status
|
||||
: ?)),
|
||||
tvec: fromMaybe (?, m_trap_updates).new_pc,
|
||||
cause: fromMaybe (?, m_trap_updates).cause,
|
||||
epc: fromMaybe (?, m_trap_updates).epc
|
||||
};
|
||||
inIfc.v_to_TV [way].put (x);
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -314,8 +314,8 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
rule rl_send_tv_reset (rg_just_after_reset);
|
||||
Bit #(64) serial_num = 0;
|
||||
fa_to_TV (way0, serial_num,
|
||||
tagged Invalid,
|
||||
no_deq_data, no_fflags, no_mstatus, no_trap_updates, no_ret_updates);
|
||||
tagged Invalid,
|
||||
no_deq_data, no_fflags, no_mstatus, no_trap_updates, no_ret_updates);
|
||||
rg_just_after_reset <= False;
|
||||
rg_serial_num <= 1;
|
||||
endrule
|
||||
@@ -328,8 +328,8 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
|
||||
rule rl_send_mip_csr_change_to_tv ((! rg_just_after_reset) && send_mip_csr_change_to_tv);
|
||||
fa_to_TV (way0, rg_serial_num,
|
||||
tagged Valid (tuple2 (pack (CSRmip), new_mip_csr_val)),
|
||||
no_deq_data, no_fflags, no_mstatus, no_trap_updates, no_ret_updates);
|
||||
tagged Valid (tuple2 (pack (CSRmip), new_mip_csr_val)),
|
||||
no_deq_data, no_fflags, no_mstatus, no_trap_updates, no_ret_updates);
|
||||
rg_old_mip_csr_val <= new_mip_csr_val;
|
||||
rg_serial_num <= rg_serial_num + 1;
|
||||
endrule
|
||||
@@ -567,7 +567,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
// This code is patterned after 'makeSystemConsistent' above
|
||||
function Action makeSystemConsistent_for_debug_mode;
|
||||
action
|
||||
inIfc.setFlushTlbs;
|
||||
inIfc.setFlushTlbs;
|
||||
|
||||
// notify TLB to keep update of CSR changes
|
||||
inIfc.setUpdateVMInfo;
|
||||
@@ -586,8 +586,8 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
// yield load reservation in cache
|
||||
inIfc.setFlushReservation;
|
||||
|
||||
inIfc.setFlushBrPred;
|
||||
inIfc.setFlushCaches;
|
||||
inIfc.setFlushBrPred;
|
||||
inIfc.setFlushCaches;
|
||||
|
||||
`ifdef SELF_INV_CACHE
|
||||
// reconcile I$
|
||||
@@ -622,9 +622,9 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
// record trap info
|
||||
Addr vaddr = ?;
|
||||
if ( (trap == tagged Exception InstAccessFault)
|
||||
|| (trap == tagged Exception InstPageFault)) begin
|
||||
vaddr = x.tval;
|
||||
end
|
||||
|| (trap == tagged Exception InstPageFault)) begin
|
||||
vaddr = x.tval;
|
||||
end
|
||||
else if(x.ppc_vaddr_csrData matches tagged VAddr .va) begin
|
||||
vaddr = getAddr(va);
|
||||
end
|
||||
@@ -636,20 +636,20 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
`ifdef RVFI_DII
|
||||
, x: x
|
||||
`endif
|
||||
});
|
||||
});
|
||||
commitTrap <= commitTrap_val;
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
f_rob_data.enq (x); // Save data to be sent to TV in rule doCommitTrap_handle, next
|
||||
`endif
|
||||
|
||||
if (verbosity >= 1) begin
|
||||
$display ("instret:%0d PC:0x%0h instr:0x%08h", rg_serial_num, x.pc, x.orig_inst,
|
||||
" iType:", fshow (x.iType), " [doCommitTrap]");
|
||||
end
|
||||
$display ("instret:%0d PC:0x%0h instr:0x%08h", rg_serial_num, x.pc, x.orig_inst,
|
||||
" iType:", fshow (x.iType), " [doCommitTrap]");
|
||||
end
|
||||
if (verbose) begin
|
||||
$display ("CommitStage.doCommitTrap_flush: deq_data: ", fshow (x));
|
||||
$display ("CommitStage.doCommitTrap_flush: commitTrap: ", fshow (commitTrap_val));
|
||||
end
|
||||
$display ("CommitStage.doCommitTrap_flush: deq_data: ", fshow (x));
|
||||
$display ("CommitStage.doCommitTrap_flush: commitTrap: ", fshow (commitTrap_val));
|
||||
end
|
||||
|
||||
// flush everything. Only increment epoch and stall fetch when we haven
|
||||
// not done it yet (we may have already done them at rename stage)
|
||||
@@ -700,44 +700,44 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
end
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
else if (trap.trap == tagged Exception Breakpoint) begin
|
||||
else if (trap.trap == tagged Exception Breakpoint) begin
|
||||
inIfc.commitCsrInstOrInterrupt; // TODO: Why?
|
||||
end
|
||||
end
|
||||
`endif
|
||||
|
||||
Bool debugger_halt = False;
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
if ((trap.trap == tagged Interrupt DebugHalt)
|
||||
|| (trap.trap == tagged Interrupt DebugStep)
|
||||
|| ((trap.trap == tagged Exception Breakpoint) && (csrf.dcsr_break_bit == 1'b1)))
|
||||
|| (trap.trap == tagged Interrupt DebugStep)
|
||||
|| ((trap.trap == tagged Exception Breakpoint) && (csrf.dcsr_break_bit == 1'b1)))
|
||||
begin
|
||||
debugger_halt = True;
|
||||
debugger_halt = True;
|
||||
|
||||
// Flush everything (tlbs, caches, reservation, branch predictor);
|
||||
// reconcilei and I; update VM info.
|
||||
makeSystemConsistent_for_debug_mode;
|
||||
// Flush everything (tlbs, caches, reservation, branch predictor);
|
||||
// reconcilei and I; update VM info.
|
||||
makeSystemConsistent_for_debug_mode;
|
||||
|
||||
// Save values in debugger CSRs
|
||||
Bit #(3) dcsr_cause = ( (trap.trap == tagged Interrupt DebugHalt)
|
||||
? 3
|
||||
: ( (trap.trap == tagged Interrupt DebugStep)
|
||||
? 4
|
||||
: 1));
|
||||
csrf.dcsr_cause_write (dcsr_cause);
|
||||
csrf.dpc_write (trap.pc);
|
||||
// Save values in debugger CSRs
|
||||
Bit #(3) dcsr_cause = ( (trap.trap == tagged Interrupt DebugHalt)
|
||||
? 3
|
||||
: ( (trap.trap == tagged Interrupt DebugStep)
|
||||
? 4
|
||||
: 1));
|
||||
csrf.dcsr_cause_write (dcsr_cause);
|
||||
csrf.dpc_write (trap.pc);
|
||||
|
||||
// Tell fetch stage to wait for redirect
|
||||
// Note: rule doCommitTrap_flush may have done this already; redundant call is ok.
|
||||
inIfc.setFetchWaitRedirect;
|
||||
inIfc.setFetchWaitFlush;
|
||||
// Tell fetch stage to wait for redirect
|
||||
// Note: rule doCommitTrap_flush may have done this already; redundant call is ok.
|
||||
inIfc.setFetchWaitRedirect;
|
||||
inIfc.setFetchWaitFlush;
|
||||
|
||||
// Go to quiescent state until debugger resumes execution
|
||||
rg_run_state <= RUN_STATE_DEBUGGER_HALTED;
|
||||
// Go to quiescent state until debugger resumes execution
|
||||
rg_run_state <= RUN_STATE_DEBUGGER_HALTED;
|
||||
|
||||
if (verbosity >= 2)
|
||||
$display ("%0d: %m.commitStage.doCommitTrap_handle; debugger halt:", cur_cycle);
|
||||
end
|
||||
if (verbosity >= 2)
|
||||
$display ("%0d: %m.commitStage.doCommitTrap_handle; debugger halt:", cur_cycle);
|
||||
end
|
||||
`endif
|
||||
|
||||
if (! debugger_halt) begin
|
||||
@@ -758,8 +758,8 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
fa_to_TV (way0, rg_serial_num,
|
||||
tagged Invalid,
|
||||
x, no_fflags, no_mstatus, tagged Valid trap_updates, no_ret_updates);
|
||||
tagged Invalid,
|
||||
x, no_fflags, no_mstatus, tagged Valid trap_updates, no_ret_updates);
|
||||
`endif
|
||||
rg_serial_num <= rg_serial_num + 1;
|
||||
|
||||
@@ -830,9 +830,9 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
|
||||
if(verbose) $display("[doCommitSystemInst] ", fshow(x));
|
||||
if (verbosity >= 1) begin
|
||||
$display("instret:%0d PC:0x%0h instr:0x%08h", rg_serial_num, x.pc, x.orig_inst,
|
||||
" iType:", fshow (x.iType), " [doCommitSystemInst]");
|
||||
end
|
||||
$display("instret:%0d PC:0x%0h instr:0x%08h", rg_serial_num, x.pc, x.orig_inst,
|
||||
" iType:", fshow (x.iType), " [doCommitSystemInst]");
|
||||
end
|
||||
|
||||
// we claim a phy reg for every inst, so commit its renaming
|
||||
regRenamingTable.commit[0].commit;
|
||||
@@ -859,12 +859,12 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
Data data_warl_xformed = csrf.warl_xform (csr_idx, csr_data);
|
||||
x.ppc_vaddr_csrData = tagged CSRData data_warl_xformed;
|
||||
x.ppc_vaddr_csrData = tagged CSRData data_warl_xformed;
|
||||
|
||||
if (x.will_dirty_fpu_state) begin
|
||||
Data old_mstatus = csrf.rd (CSRmstatus);
|
||||
new_mstatus = { 1'b1, old_mstatus [62:15], 2'b11, old_mstatus [12:0] };
|
||||
end
|
||||
if (x.will_dirty_fpu_state) begin
|
||||
Data old_mstatus = csrf.rd (CSRmstatus);
|
||||
new_mstatus = { 1'b1, old_mstatus [62:15], 2'b11, old_mstatus [12:0] };
|
||||
end
|
||||
`endif
|
||||
|
||||
// check if satp is modified or not
|
||||
@@ -885,7 +885,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
next_pc = ret_updates.new_pc;
|
||||
Scr_RET_Updates scr_ret_updates <- scaprf.sret;
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
m_ret_updates = tagged Valid ret_updates;
|
||||
m_ret_updates = tagged Valid ret_updates;
|
||||
`endif
|
||||
end
|
||||
else if(x.iType == Mret) begin
|
||||
@@ -910,8 +910,8 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
fa_to_TV (way0, rg_serial_num,
|
||||
tagged Invalid,
|
||||
x, no_fflags, new_mstatus, no_trap_updates, m_ret_updates);
|
||||
tagged Invalid,
|
||||
x, no_fflags, new_mstatus, no_trap_updates, m_ret_updates);
|
||||
`endif
|
||||
rg_serial_num <= rg_serial_num + 1;
|
||||
|
||||
@@ -1056,28 +1056,28 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
whichTrace = whichTrace + 1;
|
||||
`endif
|
||||
|
||||
if (verbosity >= 1) begin
|
||||
$display("instret:%0d PC:0x%0h instr:0x%08h", rg_serial_num + instret, x.pc, x.orig_inst,
|
||||
" iType:", fshow (x.iType), " [doCommitNormalInst [%0d]]", i);
|
||||
end
|
||||
if (verbosity >= 1) begin
|
||||
$display("instret:%0d PC:0x%0h instr:0x%08h", rg_serial_num + instret, x.pc, x.orig_inst,
|
||||
" iType:", fshow (x.iType), " [doCommitNormalInst [%0d]]", i);
|
||||
end
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
Bool init_for_way0 = (i == 0);
|
||||
match {. new_fflags, .new_mstatus} = csrf.fpuInst_csr_updates (x.fflags,
|
||||
init_for_way0,
|
||||
po_fflags,
|
||||
po_mstatus);
|
||||
po_fflags = new_fflags;
|
||||
po_mstatus = new_mstatus;
|
||||
Bool init_for_way0 = (i == 0);
|
||||
match {. new_fflags, .new_mstatus} = csrf.fpuInst_csr_updates (x.fflags,
|
||||
init_for_way0,
|
||||
po_fflags,
|
||||
po_mstatus);
|
||||
po_fflags = new_fflags;
|
||||
po_mstatus = new_mstatus;
|
||||
|
||||
fa_to_TV (i, rg_serial_num + instret,
|
||||
tagged Invalid,
|
||||
x,
|
||||
po_fflags,
|
||||
po_mstatus,
|
||||
no_trap_updates, no_ret_updates);
|
||||
fa_to_TV (i, rg_serial_num + instret,
|
||||
tagged Invalid,
|
||||
x,
|
||||
po_fflags,
|
||||
po_mstatus,
|
||||
no_trap_updates, no_ret_updates);
|
||||
`endif
|
||||
instret = instret + 1;
|
||||
instret = instret + 1;
|
||||
|
||||
// inst can be committed, deq it
|
||||
rob.deqPort[i].deq;
|
||||
@@ -1248,7 +1248,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
method Action debug_resume () if (rg_run_state == RUN_STATE_DEBUGGER_HALTED);
|
||||
rg_run_state <= RUN_STATE_RUNNING;
|
||||
if (verbosity >= 2)
|
||||
$display ("%0d: %m.commitStage.debug_resume", cur_cycle);
|
||||
$display ("%0d: %m.commitStage.debug_resume", cur_cycle);
|
||||
endmethod
|
||||
`endif
|
||||
|
||||
|
||||
@@ -230,8 +230,8 @@ typedef Bit #(TLog #(TAdd #(SupSizeX4S1, 1))) SupCntX4S1;
|
||||
// following kinds or items
|
||||
|
||||
typedef enum {Inst_None, // When we run off the end of the sequence
|
||||
Inst_16b, // A 16b instruction
|
||||
Inst_32b // A 32b instruction
|
||||
Inst_16b, // A 16b instruction
|
||||
Inst_32b // A 32b instruction
|
||||
} Inst_Kind
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
@@ -257,7 +257,7 @@ endinstance
|
||||
// This is a pure function; ActionValue is used only to allow $displays for debugging.
|
||||
|
||||
function ActionValue #(Tuple2 #(SupCntX2,
|
||||
Vector #(SupSizeX2, Bit #(16))))
|
||||
Vector #(SupSizeX2, Bit #(16))))
|
||||
fav_inst_d_to_x16s (Vector #(SupSize, Maybe #(Instruction)) inst_d);
|
||||
actionvalue
|
||||
// Convert inst_d into 16-bit parcels (v_x16)
|
||||
@@ -276,21 +276,21 @@ endfunction
|
||||
// Parse 16b parcels (v_x16) into a sequence of 16b or 32b instructions.
|
||||
// This is a pure function; ActionValue is used only to allow $displays for debugging.
|
||||
function ActionValue #(Tuple4 #(SupCntX2,
|
||||
Vector #(SupSizeX2, Inst_Item),
|
||||
Addr,
|
||||
Maybe #(Tuple3 #(Addr, Bit #(16), Bool))))
|
||||
Vector #(SupSizeX2, Inst_Item),
|
||||
Addr,
|
||||
Maybe #(Tuple3 #(Addr, Bit #(16), Bool))))
|
||||
fav_parse_insts (Bool verbose,
|
||||
Addr pc_start,
|
||||
Maybe #(Addr) pred_next_pc,
|
||||
Maybe #(Tuple3 #(Addr, Bit #(16), Bool)) pending_straddle,
|
||||
SupCntX2 n_x16s,
|
||||
Vector #(SupSizeX2, Bit #(16)) v_x16);
|
||||
Addr pc_start,
|
||||
Maybe #(Addr) pred_next_pc,
|
||||
Maybe #(Tuple3 #(Addr, Bit #(16), Bool)) pending_straddle,
|
||||
SupCntX2 n_x16s,
|
||||
Vector #(SupSizeX2, Bit #(16)) v_x16);
|
||||
actionvalue
|
||||
// Parse up to SupSizeX2 instructions (v_items) from fetched v_x16 parcels (v_x16).
|
||||
Vector #(SupSizeX2, Inst_Item) v_items = replicate (Inst_Item {pc: pc_start,
|
||||
inst_kind: Inst_None,
|
||||
orig_inst: 0,
|
||||
inst: 0});
|
||||
inst_kind: Inst_None,
|
||||
orig_inst: 0,
|
||||
inst: 0});
|
||||
Maybe #(Tuple3 #(Addr, Bit #(16), Bool)) next_straddle = tagged Invalid;
|
||||
// Start parse at parcel 0/1 depending on pc lsbs and pending straddle
|
||||
SupCntX2 j = ((pc_start [1:0] == 2'b00 || isValid(pending_straddle)) ? 0 : 1);
|
||||
@@ -301,62 +301,62 @@ function ActionValue #(Tuple4 #(SupCntX2,
|
||||
Integer n_items = 0;
|
||||
`ifndef RVFI_DII
|
||||
for (Integer i = 0; i < valueOf (SupSizeX2); i = i + 1) begin
|
||||
Inst_Kind inst_kind = Inst_None;
|
||||
Bit #(32) orig_inst = 0;
|
||||
Bit #(32) inst = 0;
|
||||
Addr next_pc = pc;
|
||||
if (j < n_x16s) begin
|
||||
if (i == 0 &&& pending_straddle matches tagged Valid {.s_pc, .s_lsbs, .s_mispred}) begin
|
||||
if (pc != s_pc + 2) begin
|
||||
$display ("FetchStage.fav_parse_insts: straddle: pc mismatch: pc = 0x%0h but s_pc = 0x%0h", pc, s_pc);
|
||||
dynamicAssert (False, "FetchStage.fav_parse_insts: straddle: pc mismatch");
|
||||
end
|
||||
Inst_Kind inst_kind = Inst_None;
|
||||
Bit #(32) orig_inst = 0;
|
||||
Bit #(32) inst = 0;
|
||||
Addr next_pc = pc;
|
||||
if (j < n_x16s) begin
|
||||
if (i == 0 &&& pending_straddle matches tagged Valid {.s_pc, .s_lsbs, .s_mispred}) begin
|
||||
if (pc != s_pc + 2) begin
|
||||
$display ("FetchStage.fav_parse_insts: straddle: pc mismatch: pc = 0x%0h but s_pc = 0x%0h", pc, s_pc);
|
||||
dynamicAssert (False, "FetchStage.fav_parse_insts: straddle: pc mismatch");
|
||||
end
|
||||
pc = s_pc;
|
||||
inst_kind = Inst_32b;
|
||||
orig_inst = { v_x16[0], s_lsbs };
|
||||
inst = orig_inst;
|
||||
j = 1;
|
||||
next_pc = s_pc + 4;
|
||||
n_items = 1;
|
||||
end
|
||||
else if (is_16b_inst (v_x16 [j])) begin
|
||||
inst_kind = Inst_16b;
|
||||
orig_inst = zeroExtend (v_x16 [j]);
|
||||
inst = fv_decode_C (misa, misa_mxl_64, v_x16 [j]); // Expand 16b inst to 32b inst
|
||||
j = j + 1;
|
||||
next_pc = pc + 2;
|
||||
n_items = i + 1;
|
||||
if (verbose)
|
||||
$display ("FetchStage.fav_parse_insts: C inst 0x%0h -> inst 0x%0h", orig_inst, inst);
|
||||
end
|
||||
else if (is_32b_inst (v_x16 [j])) begin
|
||||
if ((j + 1) < n_x16s) begin
|
||||
inst_kind = Inst_32b;
|
||||
orig_inst = { v_x16 [j+1], v_x16 [j] };
|
||||
inst = orig_inst;
|
||||
j = j + 2;
|
||||
next_pc = pc + 4;
|
||||
n_items = i + 1;
|
||||
end
|
||||
else begin
|
||||
next_straddle = tagged Valid tuple3(pc, v_x16[j], isValid(pred_next_pc));
|
||||
j = j + 1;
|
||||
// Leave next_pc unchanged and clear pred_next_pc so we
|
||||
// return the right predicted pc for the vector, which
|
||||
// excludes the pending straddle.
|
||||
pred_next_pc = tagged Invalid;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
$display ("FetchStage.fav_parse_insts: instuction is not 16b or 32b?");
|
||||
$display (" pc_start = 0x%0h, i = %0d, j = %0d, pc = 0x%0h", pc_start, i, j, pc);
|
||||
$display (" v_x16: ", fshow (v_x16));
|
||||
$display (" v_items: ", fshow (v_items));
|
||||
dynamicAssert (False, "FetchStage.fav_parse_insts: instuction is not 16b or 32b?");
|
||||
end
|
||||
end
|
||||
v_items [i] = Inst_Item {pc: pc, inst_kind: inst_kind, orig_inst: orig_inst, inst: inst};
|
||||
pc = next_pc;
|
||||
inst_kind = Inst_32b;
|
||||
orig_inst = { v_x16[0], s_lsbs };
|
||||
inst = orig_inst;
|
||||
j = 1;
|
||||
next_pc = s_pc + 4;
|
||||
n_items = 1;
|
||||
end
|
||||
else if (is_16b_inst (v_x16 [j])) begin
|
||||
inst_kind = Inst_16b;
|
||||
orig_inst = zeroExtend (v_x16 [j]);
|
||||
inst = fv_decode_C (misa, misa_mxl_64, v_x16 [j]); // Expand 16b inst to 32b inst
|
||||
j = j + 1;
|
||||
next_pc = pc + 2;
|
||||
n_items = i + 1;
|
||||
if (verbose)
|
||||
$display ("FetchStage.fav_parse_insts: C inst 0x%0h -> inst 0x%0h", orig_inst, inst);
|
||||
end
|
||||
else if (is_32b_inst (v_x16 [j])) begin
|
||||
if ((j + 1) < n_x16s) begin
|
||||
inst_kind = Inst_32b;
|
||||
orig_inst = { v_x16 [j+1], v_x16 [j] };
|
||||
inst = orig_inst;
|
||||
j = j + 2;
|
||||
next_pc = pc + 4;
|
||||
n_items = i + 1;
|
||||
end
|
||||
else begin
|
||||
next_straddle = tagged Valid tuple3(pc, v_x16[j], isValid(pred_next_pc));
|
||||
j = j + 1;
|
||||
// Leave next_pc unchanged and clear pred_next_pc so we
|
||||
// return the right predicted pc for the vector, which
|
||||
// excludes the pending straddle.
|
||||
pred_next_pc = tagged Invalid;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
$display ("FetchStage.fav_parse_insts: instuction is not 16b or 32b?");
|
||||
$display (" pc_start = 0x%0h, i = %0d, j = %0d, pc = 0x%0h", pc_start, i, j, pc);
|
||||
$display (" v_x16: ", fshow (v_x16));
|
||||
$display (" v_items: ", fshow (v_items));
|
||||
dynamicAssert (False, "FetchStage.fav_parse_insts: instuction is not 16b or 32b?");
|
||||
end
|
||||
end
|
||||
v_items [i] = Inst_Item {pc: pc, inst_kind: inst_kind, orig_inst: orig_inst, inst: inst};
|
||||
pc = next_pc;
|
||||
end
|
||||
`else
|
||||
for (Integer i = 0; i < valueOf(SupSize); i = i + 1) begin
|
||||
@@ -370,11 +370,11 @@ function ActionValue #(Tuple4 #(SupCntX2,
|
||||
`endif
|
||||
|
||||
if (verbose) begin
|
||||
$display ("FetchStage.fav_parse_insts:");
|
||||
$display (" v_x16: ", fshow (v_x16), " n_x16s: %d", n_x16s);
|
||||
$display (" n_items: %0d", n_items);
|
||||
$display (" v_items: ", fshow (v_items));
|
||||
$display (" next_straddle: ", fshow (next_straddle));
|
||||
$display ("FetchStage.fav_parse_insts:");
|
||||
$display (" v_x16: ", fshow (v_x16), " n_x16s: %d", n_x16s);
|
||||
$display (" n_items: %0d", n_items);
|
||||
$display (" v_items: ", fshow (v_items));
|
||||
$display (" next_straddle: ", fshow (next_straddle));
|
||||
end
|
||||
|
||||
return tuple4(fromInteger(n_items), v_items, fromMaybe(pc, pred_next_pc), next_straddle);
|
||||
@@ -496,24 +496,24 @@ module mkFetchStage(FetchStage);
|
||||
|
||||
function ActionValue #(Tuple2 #(Integer, Maybe #(Addr))) fav_pred_next_pc (Addr pc);
|
||||
actionvalue
|
||||
Addr prev_PC = pc;
|
||||
Maybe #(Addr) pred_next_pc = nextAddrPred.predPc (prev_PC);
|
||||
Integer posLastSupX2 = 0;
|
||||
Bool done = False;
|
||||
for (Integer i = 0; i < valueOf (SupSizeX2); i = i + 1) begin
|
||||
if (! done) begin
|
||||
Bool isLastX2 = (i == (valueOf (SupSizeX2) - 1)) || ((pc[1:0] != 2'b00) && (i == (valueOf (SupSizeX2) - 2)));
|
||||
Bool lastInstInCacheLine = (getLineInstOffset (prev_PC) == maxBound) && (prev_PC[1:0] != 2'b00);
|
||||
Bool isJump = isValid(pred_next_pc);
|
||||
done = isLastX2 || lastInstInCacheLine || isJump;
|
||||
posLastSupX2 = i;
|
||||
if (! done) begin
|
||||
prev_PC = prev_PC + 2;
|
||||
pred_next_pc = nextAddrPred.predPc (prev_PC);
|
||||
end
|
||||
end
|
||||
end
|
||||
return tuple2 (posLastSupX2, pred_next_pc);
|
||||
Addr prev_PC = pc;
|
||||
Maybe #(Addr) pred_next_pc = nextAddrPred.predPc (prev_PC);
|
||||
Integer posLastSupX2 = 0;
|
||||
Bool done = False;
|
||||
for (Integer i = 0; i < valueOf (SupSizeX2); i = i + 1) begin
|
||||
if (! done) begin
|
||||
Bool isLastX2 = (i == (valueOf (SupSizeX2) - 1)) || ((pc[1:0] != 2'b00) && (i == (valueOf (SupSizeX2) - 2)));
|
||||
Bool lastInstInCacheLine = (getLineInstOffset (prev_PC) == maxBound) && (prev_PC[1:0] != 2'b00);
|
||||
Bool isJump = isValid(pred_next_pc);
|
||||
done = isLastX2 || lastInstInCacheLine || isJump;
|
||||
posLastSupX2 = i;
|
||||
if (! done) begin
|
||||
prev_PC = prev_PC + 2;
|
||||
pred_next_pc = nextAddrPred.predPc (prev_PC);
|
||||
end
|
||||
end
|
||||
end
|
||||
return tuple2 (posLastSupX2, pred_next_pc);
|
||||
endactionvalue
|
||||
endfunction
|
||||
|
||||
@@ -609,29 +609,29 @@ module mkFetchStage(FetchStage);
|
||||
default: begin
|
||||
// Access fault
|
||||
cause = Valid (InstAccessFault);
|
||||
// Without 'C' extension:
|
||||
// Addr align32b_mask = 'h3;
|
||||
// tval = (in.pc & (~ align32b_mask));
|
||||
Addr align16b_mask = 'h1;
|
||||
tval = (in.pc & (~ align16b_mask));
|
||||
// Without 'C' extension:
|
||||
// Addr align32b_mask = 'h3;
|
||||
// tval = (in.pc & (~ align32b_mask));
|
||||
Addr align16b_mask = 'h1;
|
||||
tval = (in.pc & (~ align16b_mask));
|
||||
end
|
||||
endcase
|
||||
end
|
||||
else begin
|
||||
// TLB exception: record the request address
|
||||
// TLB exception: record the request address
|
||||
// Without 'C' extension:
|
||||
// Addr align32b_mask = 'h3;
|
||||
// tval = (in.pc & (~ align32b_mask));
|
||||
Addr align16b_mask = 'h1;
|
||||
tval = (in.pc & (~ align16b_mask));
|
||||
end
|
||||
end
|
||||
`endif
|
||||
|
||||
let out = Fetch2ToFetch3 {
|
||||
pc: in.pc,
|
||||
pred_next_pc: in.pred_next_pc,
|
||||
cause: cause,
|
||||
tval: tval,
|
||||
tval: tval,
|
||||
access_mmio: access_mmio,
|
||||
fetch3_epoch: in.fetch3_epoch,
|
||||
decode_epoch: in.decode_epoch,
|
||||
@@ -639,9 +639,9 @@ module mkFetchStage(FetchStage);
|
||||
f22f3.enq(tuple2(nbSupX2,out));
|
||||
|
||||
if (verbosity >= 2) begin
|
||||
$display ("----------------");
|
||||
$display ("Fetch2: TLB response pyhs_pc 0x%0h cause ", phys_pc, fshow (cause));
|
||||
$display ("Fetch2: f2_tof3.enq: nbSupX2 %0d out ", nbSupX2, fshow (out));
|
||||
$display ("----------------");
|
||||
$display ("Fetch2: TLB response pyhs_pc 0x%0h cause ", phys_pc, fshow (cause));
|
||||
$display ("Fetch2: f2_tof3.enq: nbSupX2 %0d out ", nbSupX2, fshow (out));
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -869,164 +869,164 @@ module mkFetchStage(FetchStage);
|
||||
|
||||
for (Integer i = 0; i < valueof(SupSize); i=i+1) begin
|
||||
if (inst_data[i].inst_kind != Inst_None && (fromInteger(i) <= nbSup)) begin
|
||||
// Inst_16b or Inst_32b
|
||||
// get the input to decode
|
||||
let inst_data_shifted = shiftInAtN (inst_data, ?); // for predicted PCs
|
||||
let in = InstrFromFetch3 {
|
||||
pc: inst_data[i].pc,
|
||||
// last inst, next pc may not be pc+2/pc+4
|
||||
ppc: ((fromInteger(i) == nbSup)
|
||||
? decodeIn.pred_next_pc
|
||||
: inst_data_shifted[i].pc),
|
||||
decode_epoch: decodeIn.decode_epoch,
|
||||
main_epoch: decodeIn.main_epoch,
|
||||
inst: inst_data [i].inst, // original 32b inst, or expanded version of 16b inst
|
||||
cause: decodeIn.cause
|
||||
};
|
||||
let cause = in.cause;
|
||||
Addr tval = decodeIn.tval;
|
||||
if (verbose)
|
||||
$display("Decode: %0d in = ", i, fshow (in));
|
||||
// Inst_16b or Inst_32b
|
||||
// get the input to decode
|
||||
let inst_data_shifted = shiftInAtN (inst_data, ?); // for predicted PCs
|
||||
let in = InstrFromFetch3 {
|
||||
pc: inst_data[i].pc,
|
||||
// last inst, next pc may not be pc+2/pc+4
|
||||
ppc: ((fromInteger(i) == nbSup)
|
||||
? decodeIn.pred_next_pc
|
||||
: inst_data_shifted[i].pc),
|
||||
decode_epoch: decodeIn.decode_epoch,
|
||||
main_epoch: decodeIn.main_epoch,
|
||||
inst: inst_data [i].inst, // original 32b inst, or expanded version of 16b inst
|
||||
cause: decodeIn.cause
|
||||
};
|
||||
let cause = in.cause;
|
||||
Addr tval = decodeIn.tval;
|
||||
if (verbose)
|
||||
$display("Decode: %0d in = ", i, fshow (in));
|
||||
|
||||
// do decode and branch prediction
|
||||
// Drop here if does not match the decode_epoch.
|
||||
if (in.decode_epoch == decode_epoch_local) begin
|
||||
doAssert(in.main_epoch == f_main_epoch, "main epoch must match");
|
||||
// do decode and branch prediction
|
||||
// Drop here if does not match the decode_epoch.
|
||||
if (in.decode_epoch == decode_epoch_local) begin
|
||||
doAssert(in.main_epoch == f_main_epoch, "main epoch must match");
|
||||
|
||||
let decode_result = decode(in.inst); // Decode 32b inst, or 32b expansion of 16b inst
|
||||
let decode_result = decode(in.inst); // Decode 32b inst, or 32b expansion of 16b inst
|
||||
|
||||
// update cause and tval if decode exception and no earlier (TLB) exception
|
||||
if (!isValid(cause)) begin
|
||||
cause = decode_result.illegalInst ? tagged Valid IllegalInst : tagged Invalid;
|
||||
tval = decodeIn.tval;
|
||||
end
|
||||
// update cause and tval if decode exception and no earlier (TLB) exception
|
||||
if (!isValid(cause)) begin
|
||||
cause = decode_result.illegalInst ? tagged Valid IllegalInst : tagged Invalid;
|
||||
tval = decodeIn.tval;
|
||||
end
|
||||
|
||||
let dInst = decode_result.dInst;
|
||||
let regs = decode_result.regs;
|
||||
DirPredTrainInfo dp_train = ?; // dir pred training bookkeeping
|
||||
let regs = decode_result.regs;
|
||||
DirPredTrainInfo dp_train = ?; // dir pred training bookkeeping
|
||||
|
||||
// update predicted next pc
|
||||
if (!isValid(cause)) begin
|
||||
// direction predict
|
||||
Bool pred_taken = False;
|
||||
if(dInst.iType == Br) begin
|
||||
let pred_res <- dirPred.pred[i].pred(in.pc);
|
||||
pred_taken = pred_res.taken;
|
||||
dp_train = pred_res.train;
|
||||
end
|
||||
// update predicted next pc
|
||||
if (!isValid(cause)) begin
|
||||
// direction predict
|
||||
Bool pred_taken = False;
|
||||
if(dInst.iType == Br) begin
|
||||
let pred_res <- dirPred.pred[i].pred(in.pc);
|
||||
pred_taken = pred_res.taken;
|
||||
dp_train = pred_res.train;
|
||||
end
|
||||
Maybe#(Addr) nextPc = decodeBrPred(in.pc, dInst, pred_taken, (inst_data[i].inst_kind == Inst_32b));
|
||||
|
||||
// return address stack link reg is x1 or x5
|
||||
function Bool linkedR(Maybe#(ArchRIndx) register);
|
||||
Bool res = False;
|
||||
if (register matches tagged Valid .r &&& (r == tagged Gpr 1 || r == tagged Gpr 5)) begin
|
||||
res = True;
|
||||
end
|
||||
return res;
|
||||
endfunction
|
||||
// return address stack link reg is x1 or x5
|
||||
function Bool linkedR(Maybe#(ArchRIndx) register);
|
||||
Bool res = False;
|
||||
if (register matches tagged Valid .r &&& (r == tagged Gpr 1 || r == tagged Gpr 5)) begin
|
||||
res = True;
|
||||
end
|
||||
return res;
|
||||
endfunction
|
||||
Bool dst_link = linkedR(regs.dst);
|
||||
Bool src1_link = linkedR(regs.src1);
|
||||
Addr push_addr = in.pc + ((inst_data[i].inst_kind == Inst_32b) ? 4 : 2);
|
||||
Bool src1_link = linkedR(regs.src1);
|
||||
Addr push_addr = in.pc + ((inst_data[i].inst_kind == Inst_32b) ? 4 : 2);
|
||||
|
||||
Addr pop_addr = ras.ras[i].first;
|
||||
if (dInst.iType == J && dst_link) begin
|
||||
// rs1 is invalid, i.e., not link: push
|
||||
ras.ras[i].popPush(False, Valid (push_addr));
|
||||
end
|
||||
Addr pop_addr = ras.ras[i].first;
|
||||
if (dInst.iType == J && dst_link) begin
|
||||
// rs1 is invalid, i.e., not link: push
|
||||
ras.ras[i].popPush(False, Valid (push_addr));
|
||||
end
|
||||
else if (dInst.iType == Jr) begin // jalr
|
||||
if (!dst_link && src1_link) begin
|
||||
// rd is link while rs1 is not: pop
|
||||
nextPc = Valid (pop_addr);
|
||||
ras.ras[i].popPush(True, Invalid);
|
||||
end
|
||||
if (!dst_link && src1_link) begin
|
||||
// rd is link while rs1 is not: pop
|
||||
nextPc = Valid (pop_addr);
|
||||
ras.ras[i].popPush(True, Invalid);
|
||||
end
|
||||
else if (!src1_link && dst_link) begin
|
||||
// rs1 is not link while rd is link: push
|
||||
ras.ras[i].popPush(False, Valid (push_addr));
|
||||
end
|
||||
// rs1 is not link while rd is link: push
|
||||
ras.ras[i].popPush(False, Valid (push_addr));
|
||||
end
|
||||
else if (dst_link && src1_link) begin
|
||||
// both rd and rs1 are links
|
||||
if (regs.src1 != regs.dst) begin
|
||||
// not same reg: first pop, then push
|
||||
nextPc = Valid (pop_addr);
|
||||
ras.ras[i].popPush(True, Valid (push_addr));
|
||||
end
|
||||
// both rd and rs1 are links
|
||||
if (regs.src1 != regs.dst) begin
|
||||
// not same reg: first pop, then push
|
||||
nextPc = Valid (pop_addr);
|
||||
ras.ras[i].popPush(True, Valid (push_addr));
|
||||
end
|
||||
else begin
|
||||
// same reg: push
|
||||
ras.ras[i].popPush(False, Valid (push_addr));
|
||||
end
|
||||
// same reg: push
|
||||
ras.ras[i].popPush(False, Valid (push_addr));
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if(verbose) begin
|
||||
$display("Branch prediction: ", fshow(dInst.iType), " ; ", fshow(in.pc), " ; ",
|
||||
fshow(in.ppc), " ; ", fshow(pred_taken), " ; ", fshow(nextPc));
|
||||
end
|
||||
$display("Branch prediction: ", fshow(dInst.iType), " ; ", fshow(in.pc), " ; ",
|
||||
fshow(in.ppc), " ; ", fshow(pred_taken), " ; ", fshow(nextPc));
|
||||
end
|
||||
|
||||
if (i == 0 && decodeIn.mispred_first_half) begin
|
||||
// We predicted a taken branch for PC, but this is an
|
||||
// uncompressed instruction, so we train it to fetch
|
||||
// the other half in future.
|
||||
trainNAP = Valid (TrainNAP {pc: in.pc, nextPc: in.pc + 2});
|
||||
end
|
||||
if (i == 0 && decodeIn.mispred_first_half) begin
|
||||
// We predicted a taken branch for PC, but this is an
|
||||
// uncompressed instruction, so we train it to fetch
|
||||
// the other half in future.
|
||||
trainNAP = Valid (TrainNAP {pc: in.pc, nextPc: in.pc + 2});
|
||||
end
|
||||
|
||||
// check previous mispred
|
||||
if (nextPc matches tagged Valid .decode_pred_next_pc &&& decode_pred_next_pc != in.ppc) begin
|
||||
if (verbose) $display("ppc and decodeppc : %h %h", in.ppc, decode_pred_next_pc);
|
||||
decode_epoch_local = !decode_epoch_local;
|
||||
redirectPc = Valid (decode_pred_next_pc); // record redirect next pc
|
||||
in.ppc = decode_pred_next_pc;
|
||||
// train next addr pred when mispredict
|
||||
let last_x16_pc = in.pc + ((inst_data[i].inst_kind == Inst_32b) ? 2 : 0);
|
||||
if (!decodeIn.mispred_first_half)
|
||||
trainNAP = Valid (TrainNAP {pc: last_x16_pc, nextPc: decode_pred_next_pc});
|
||||
if (nextPc matches tagged Valid .decode_pred_next_pc &&& decode_pred_next_pc != in.ppc) begin
|
||||
if (verbose) $display("ppc and decodeppc : %h %h", in.ppc, decode_pred_next_pc);
|
||||
decode_epoch_local = !decode_epoch_local;
|
||||
redirectPc = Valid (decode_pred_next_pc); // record redirect next pc
|
||||
in.ppc = decode_pred_next_pc;
|
||||
// train next addr pred when mispredict
|
||||
let last_x16_pc = in.pc + ((inst_data[i].inst_kind == Inst_32b) ? 2 : 0);
|
||||
if (!decodeIn.mispred_first_half)
|
||||
trainNAP = Valid (TrainNAP {pc: last_x16_pc, nextPc: decode_pred_next_pc});
|
||||
`ifdef RVFI_DII
|
||||
nextId = fromMaybe(nextId,ids[i]) + 1;
|
||||
`endif
|
||||
`ifdef PERF_COUNT
|
||||
// performance stats: record decode redirect
|
||||
doAssert(redirectInst == Invalid, "at most 1 decode redirect per cycle");
|
||||
redirectInst = Valid (dInst.iType);
|
||||
// performance stats: record decode redirect
|
||||
doAssert(redirectInst == Invalid, "at most 1 decode redirect per cycle");
|
||||
redirectInst = Valid (dInst.iType);
|
||||
`endif
|
||||
end
|
||||
end // if (!isValid(cause))
|
||||
end
|
||||
end // if (!isValid(cause))
|
||||
let out = FromFetchStage{pc: in.pc,
|
||||
ppc: in.ppc,
|
||||
main_epoch: in.main_epoch,
|
||||
dpTrain: dp_train,
|
||||
inst: in.inst,
|
||||
dInst: dInst,
|
||||
orig_inst: inst_data[i].orig_inst,
|
||||
regs: decode_result.regs,
|
||||
cause: cause,
|
||||
ppc: in.ppc,
|
||||
main_epoch: in.main_epoch,
|
||||
dpTrain: dp_train,
|
||||
inst: in.inst,
|
||||
dInst: dInst,
|
||||
orig_inst: inst_data[i].orig_inst,
|
||||
regs: decode_result.regs,
|
||||
cause: cause,
|
||||
`ifdef RVFI_DII
|
||||
diid: fromMaybe(?,ids[i]),
|
||||
`endif
|
||||
tval: tval};
|
||||
out_fifo.enqS[i].enq(out);
|
||||
tval: tval};
|
||||
out_fifo.enqS[i].enq(out);
|
||||
if (verbosity >= 1) begin
|
||||
$write ("%0d: %m.rule doDecode: out_fifo.enqS[%0d].enq", cur_cycle, i);
|
||||
$display (" pc %0h inst %08h", out.pc, out.orig_inst);
|
||||
end
|
||||
$write ("%0d: %m.rule doDecode: out_fifo.enqS[%0d].enq", cur_cycle, i);
|
||||
$display (" pc %0h inst %08h", out.pc, out.orig_inst);
|
||||
end
|
||||
if (verbosity >= 2) begin
|
||||
$display (" ", fshow(out));
|
||||
end
|
||||
end // if (in.decode_epoch == decode_epoch_local)
|
||||
$display (" ", fshow(out));
|
||||
end
|
||||
end // if (in.decode_epoch == decode_epoch_local)
|
||||
else begin
|
||||
if (verbose) $display("Drop decoded within a superscalar");
|
||||
// just drop wrong path instructions
|
||||
end
|
||||
end
|
||||
if (verbose) $display("Drop decoded within a superscalar");
|
||||
// just drop wrong path instructions
|
||||
end
|
||||
end
|
||||
else if (inst_data[i].inst_kind == Inst_None && fromInteger(i) <= nbSup) begin
|
||||
// inst num is less than expected; this should not happen
|
||||
// because both I$ and boot rom are aligned to cache line
|
||||
// size.
|
||||
// inst num is less than expected; this should not happen
|
||||
// because both I$ and boot rom are aligned to cache line
|
||||
// size.
|
||||
doAssert(False, "Fetched insts not enough");
|
||||
end // if (inst_data[i].inst_kind!= Inst_None && (fromInteger(i) <= nbSup))
|
||||
end // if (inst_data[i].inst_kind!= Inst_None && (fromInteger(i) <= nbSup))
|
||||
end // for (Integer i = 0; i < valueof(SupSize); i=i+1)
|
||||
|
||||
// update PC and epoch
|
||||
if(redirectPc matches tagged Valid .nextPc) begin
|
||||
pc_reg[pc_decode_port] <= nextPc;
|
||||
pc_reg[pc_decode_port] <= nextPc;
|
||||
`ifdef RVFI_DII
|
||||
dii_id_next[pc_decode_port] <= nextId;
|
||||
`endif
|
||||
@@ -1034,17 +1034,17 @@ module mkFetchStage(FetchStage);
|
||||
decode_epoch[0] <= decode_epoch_local;
|
||||
// send training data for next addr pred
|
||||
if (trainNAP matches tagged Valid .x) begin
|
||||
napTrainByDecQ.enq(x);
|
||||
napTrainByDecQ.enq(x);
|
||||
end
|
||||
`ifdef PERF_COUNT
|
||||
// performance counter: check whether redirect happens
|
||||
if(redirectInst matches tagged Valid .iType &&& doStats) begin
|
||||
case(iType)
|
||||
Br: decRedirectBrCnt.incr(1);
|
||||
J : decRedirectJmpCnt.incr(1);
|
||||
Jr: decRedirectJrCnt.incr(1);
|
||||
default: decRedirectOtherCnt.incr(1);
|
||||
endcase
|
||||
case(iType)
|
||||
Br: decRedirectBrCnt.incr(1);
|
||||
J : decRedirectJmpCnt.incr(1);
|
||||
Jr: decRedirectJrCnt.incr(1);
|
||||
default: decRedirectOtherCnt.incr(1);
|
||||
endcase
|
||||
end
|
||||
`endif
|
||||
end // if (decodeIn.main_epoch == f_main_epoch)
|
||||
|
||||
@@ -158,9 +158,9 @@ interface MemExeInput;
|
||||
// ROB
|
||||
method Addr rob_getPC(InstTag t);
|
||||
method Action rob_setExecuted_doFinishMem(InstTag t,
|
||||
Addr vaddr,
|
||||
Data store_data, ByteEn store_data_BE,
|
||||
Bool access_at_commit, Bool non_mmio_st_done
|
||||
Addr vaddr,
|
||||
Data store_data, ByteEn store_data_BE,
|
||||
Bool access_at_commit, Bool non_mmio_st_done
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
@@ -486,8 +486,8 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
shiftedBE: shiftBE,
|
||||
vaddr: vaddr,
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
store_data: data,
|
||||
store_data_BE: origBE,
|
||||
store_data: data,
|
||||
store_data_BE: origBE,
|
||||
`endif
|
||||
misaligned: memAddrMisaligned(vaddr, origBE)
|
||||
},
|
||||
@@ -699,7 +699,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
inIfc.writeRegFile(dst.indx, res.data);
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
inIfc.rob_setExecuted_doFinishMem_RegData (res.instTag, res.data);
|
||||
inIfc.rob_setExecuted_doFinishMem_RegData (res.instTag, res.data);
|
||||
`endif
|
||||
|
||||
`ifdef PERF_COUNT
|
||||
@@ -862,7 +862,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
inIfc.writeRegFile(dst.indx, resp);
|
||||
inIfc.setRegReadyAggr_mem(dst.indx);
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
inIfc.rob_setExecuted_doFinishMem_RegData (lsqDeqLd.instTag, resp);
|
||||
inIfc.rob_setExecuted_doFinishMem_RegData (lsqDeqLd.instTag, resp);
|
||||
`endif
|
||||
end
|
||||
inIfc.rob_setExecuted_deqLSQ(
|
||||
@@ -950,7 +950,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
inIfc.writeRegFile(dst.indx, resp);
|
||||
inIfc.setRegReadyAggr_mem(dst.indx);
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
inIfc.rob_setExecuted_doFinishMem_RegData (lsqDeqLd.instTag, resp);
|
||||
inIfc.rob_setExecuted_doFinishMem_RegData (lsqDeqLd.instTag, resp);
|
||||
`endif
|
||||
end
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqLd.instTag, Invalid, Invalid
|
||||
@@ -1201,7 +1201,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
inIfc.writeRegFile(dst.indx, resp);
|
||||
inIfc.setRegReadyAggr_mem(dst.indx);
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
inIfc.rob_setExecuted_doFinishMem_RegData (lsqDeqSt.instTag, resp);
|
||||
inIfc.rob_setExecuted_doFinishMem_RegData (lsqDeqSt.instTag, resp);
|
||||
`endif
|
||||
end
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, Invalid, Invalid
|
||||
@@ -1307,7 +1307,7 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline);
|
||||
inIfc.writeRegFile(dst.indx, resp);
|
||||
inIfc.setRegReadyAggr_mem(dst.indx);
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
inIfc.rob_setExecuted_doFinishMem_RegData (lsqDeqSt.instTag, resp);
|
||||
inIfc.rob_setExecuted_doFinishMem_RegData (lsqDeqSt.instTag, resp);
|
||||
`endif
|
||||
end
|
||||
inIfc.rob_setExecuted_deqLSQ(lsqDeqSt.instTag, Invalid, Invalid
|
||||
|
||||
@@ -180,11 +180,11 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
|
||||
function Action fa_step_check;
|
||||
action
|
||||
if (csrf.dcsr_step_bit == 1'b1) begin
|
||||
rg_m_halt_req <= tagged Valid DebugStep;
|
||||
if (verbosity >= 2)
|
||||
$display ("%0d: %m.renameStage.fa_step_check: rg_m_halt_req <= tagged Valid DebugStep", cur_cycle);
|
||||
end
|
||||
if (csrf.dcsr_step_bit == 1'b1) begin
|
||||
rg_m_halt_req <= tagged Valid DebugStep;
|
||||
if (verbosity >= 2)
|
||||
$display ("%0d: %m.renameStage.fa_step_check: rg_m_halt_req <= tagged Valid DebugStep", cur_cycle);
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
`endif
|
||||
@@ -221,8 +221,8 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
function Bool fn_ArchReg_is_FpuReg (Maybe #(ArchRIndx) m_arch_r_indx);
|
||||
Bool result = False;
|
||||
if (m_arch_r_indx matches tagged Valid .arch_r_indx)
|
||||
if (arch_r_indx matches tagged Fpu .fpu_r_index)
|
||||
result = True;
|
||||
if (arch_r_indx matches tagged Fpu .fpu_r_index)
|
||||
result = True;
|
||||
return result;
|
||||
endfunction
|
||||
|
||||
@@ -235,46 +235,46 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
|
||||
// If Fpu regs are accessed, trap if mstatus_fs is "Off" (2'b00)
|
||||
Bool fpr_access = ( fn_ArchReg_is_FpuReg (x.regs.src1)
|
||||
|| fn_ArchReg_is_FpuReg (x.regs.src2)
|
||||
|| isValid (x.regs.src3)
|
||||
|| fn_ArchReg_is_FpuReg (x.regs.dst));
|
||||
|| fn_ArchReg_is_FpuReg (x.regs.src2)
|
||||
|| isValid (x.regs.src3)
|
||||
|| fn_ArchReg_is_FpuReg (x.regs.dst));
|
||||
let mstatus = csrf.rd (CSRmstatus);
|
||||
Bool fs_trap = ((mstatus [14:13] == 2'b00) && fpr_access);
|
||||
|
||||
// Check CSR access permission
|
||||
Bool csr_access_trap = False;
|
||||
if (x.dInst.iType == Csr) begin
|
||||
Bit #(12) csr_addr = case (x.dInst.csr) matches
|
||||
tagged Valid .c: pack (c);
|
||||
default: 12'hCFF;
|
||||
endcase;
|
||||
let rs1 = case (x.regs.src2) matches
|
||||
tagged Valid (tagged Gpr .r) : r;
|
||||
default: 0;
|
||||
endcase;
|
||||
let imm = case (x.dInst.imm) matches
|
||||
tagged Valid .n: n;
|
||||
default: 0;
|
||||
endcase;
|
||||
Bool writes_csr = ((x.dInst.execFunc == tagged Alu Csrw) || (rs1 != 0) || (imm != 0));
|
||||
Bool read_only = (csr_addr [11:10] == 2'b11);
|
||||
Bit #(12) csr_addr = case (x.dInst.csr) matches
|
||||
tagged Valid .c: pack (c);
|
||||
default: 12'hCFF;
|
||||
endcase;
|
||||
let rs1 = case (x.regs.src2) matches
|
||||
tagged Valid (tagged Gpr .r) : r;
|
||||
default: 0;
|
||||
endcase;
|
||||
let imm = case (x.dInst.imm) matches
|
||||
tagged Valid .n: n;
|
||||
default: 0;
|
||||
endcase;
|
||||
Bool writes_csr = ((x.dInst.execFunc == tagged Alu Csrw) || (rs1 != 0) || (imm != 0));
|
||||
Bool read_only = (csr_addr [11:10] == 2'b11);
|
||||
Bool write_deny = (writes_csr && read_only);
|
||||
Bool priv_deny = (csrf.decodeInfo.prv < csr_addr [9:8]);
|
||||
Bool unimplemented = (csr_addr == 12'h8ff); // Added by Bluespec
|
||||
csr_access_trap = (write_deny || priv_deny || unimplemented);
|
||||
end
|
||||
Bool priv_deny = (csrf.decodeInfo.prv < csr_addr [9:8]);
|
||||
Bool unimplemented = (csr_addr == 12'h8ff); // Added by Bluespec
|
||||
csr_access_trap = (write_deny || priv_deny || unimplemented);
|
||||
end
|
||||
|
||||
// Check WFI trap (using a time-out of 0)
|
||||
Bit #(32) inst_WFI = 32'h_1050_0073;
|
||||
Bit #(1) mstatus_tw = mstatus [21];
|
||||
Bool wfi_trap = ( (x.inst == inst_WFI)
|
||||
&& (mstatus_tw == 1'b1)
|
||||
&& (csrf.decodeInfo.prv < prvM));
|
||||
&& (mstatus_tw == 1'b1)
|
||||
&& (csrf.decodeInfo.prv < prvM));
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
if (rg_m_halt_req matches tagged Valid .cause) begin
|
||||
// Stop due to debugger halt or step
|
||||
trap = tagged Valid (tagged Interrupt cause);
|
||||
// Stop due to debugger halt or step
|
||||
trap = tagged Valid (tagged Interrupt cause);
|
||||
end else
|
||||
`endif
|
||||
|
||||
@@ -288,9 +288,9 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
// newly found exception
|
||||
trap = tagged Valid (tagged Exception fromMaybe(?, new_exception));
|
||||
end
|
||||
else if (fs_trap || csr_access_trap || wfi_trap) begin
|
||||
else if (fs_trap || csr_access_trap || wfi_trap) begin
|
||||
trap = tagged Valid (tagged Exception IllegalInst);
|
||||
end
|
||||
end
|
||||
return trap;
|
||||
endfunction
|
||||
|
||||
@@ -324,12 +324,12 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
fa_step_check;
|
||||
|
||||
if (verbosity >= 1) begin
|
||||
if (firstTrap == tagged Valid (tagged Interrupt DebugHalt))
|
||||
$display ("%0d: %m.renameStage.doRenaming_Trap: DebugHalt", cur_cycle);
|
||||
else if (firstTrap == tagged Valid (tagged Interrupt DebugStep))
|
||||
$display ("%0d: %m.renameStage.doRenaming_Trap: DebugStep", cur_cycle);
|
||||
else if (firstTrap == tagged Valid (tagged Exception Breakpoint))
|
||||
$display ("%0d: %m.renameStage.doRenaming_Trap: Breakpoint", cur_cycle);
|
||||
if (firstTrap == tagged Valid (tagged Interrupt DebugHalt))
|
||||
$display ("%0d: %m.renameStage.doRenaming_Trap: DebugHalt", cur_cycle);
|
||||
else if (firstTrap == tagged Valid (tagged Interrupt DebugStep))
|
||||
$display ("%0d: %m.renameStage.doRenaming_Trap: DebugStep", cur_cycle);
|
||||
else if (firstTrap == tagged Valid (tagged Exception Breakpoint))
|
||||
$display ("%0d: %m.renameStage.doRenaming_Trap: Breakpoint", cur_cycle);
|
||||
end
|
||||
`endif
|
||||
let x = fetchStage.pipelines[0].first;
|
||||
@@ -353,18 +353,18 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
incrEpochStallFetch;
|
||||
// just place it in the reorder buffer
|
||||
let y = ToReorderBuffer{pc: pc,
|
||||
orig_inst: orig_inst,
|
||||
orig_inst: orig_inst,
|
||||
iType: dInst.iType,
|
||||
dst: arch_regs.dst,
|
||||
dst_data: ?, // Available only after execution
|
||||
dst: arch_regs.dst,
|
||||
dst_data: ?, // Available only after execution
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
store_data: ?,
|
||||
store_data_BE: ?,
|
||||
store_data: ?,
|
||||
store_data_BE: ?,
|
||||
`endif
|
||||
csr: dInst.csr,
|
||||
claimed_phy_reg: False, // no renaming is done
|
||||
trap: firstTrap,
|
||||
tval: tval,
|
||||
tval: tval,
|
||||
// default values of FullResult
|
||||
ppc_vaddr_csrData: PPC (setAddr(almightyCap, pc).value), // default use PPC
|
||||
fflags: 0,
|
||||
@@ -390,7 +390,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
else if (firstTrap == tagged Valid (tagged Exception Breakpoint)) begin
|
||||
inIfc.issueCsrInstOrInterrupt;
|
||||
end
|
||||
end
|
||||
`endif
|
||||
|
||||
`ifdef CHECK_DEADLOCK
|
||||
@@ -540,29 +540,29 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
|
||||
// CSR instrs that touch certain FP CSRs will dirty FP state.
|
||||
if (dInst.csr matches tagged Valid .csr
|
||||
&&& ((dInst.iType == Csr)
|
||||
&& ((csr == CSRfflags) || (csr == CSRfrm) || (csr == CSRfcsr))))
|
||||
begin
|
||||
Bool is_CSRR_W = (dInst.execFunc == tagged Alu Csrw);
|
||||
Bool rs1_is_0 = ((arch_regs.src2 == tagged Valid (tagged Gpr 0))
|
||||
|| (dInst.imm == tagged Valid 0));
|
||||
will_dirty_fpu_state = (is_CSRR_W || (! rs1_is_0));
|
||||
end
|
||||
&&& ((dInst.iType == Csr)
|
||||
&& ((csr == CSRfflags) || (csr == CSRfrm) || (csr == CSRfcsr))))
|
||||
begin
|
||||
Bool is_CSRR_W = (dInst.execFunc == tagged Alu Csrw);
|
||||
Bool rs1_is_0 = ((arch_regs.src2 == tagged Valid (tagged Gpr 0))
|
||||
|| (dInst.imm == tagged Valid 0));
|
||||
will_dirty_fpu_state = (is_CSRR_W || (! rs1_is_0));
|
||||
end
|
||||
|
||||
RobInstState rob_inst_state = to_exec ? NotDone : Executed;
|
||||
let y = ToReorderBuffer{pc: pc,
|
||||
orig_inst: orig_inst,
|
||||
orig_inst: orig_inst,
|
||||
iType: dInst.iType,
|
||||
dst: arch_regs.dst,
|
||||
dst_data: ?, // Available only after execution
|
||||
dst: arch_regs.dst,
|
||||
dst_data: ?, // Available only after execution
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
store_data: ?,
|
||||
store_data_BE: ?,
|
||||
store_data: ?,
|
||||
store_data_BE: ?,
|
||||
`endif
|
||||
csr: dInst.csr,
|
||||
claimed_phy_reg: True, // XXX we always claim a free reg in rename
|
||||
trap: Invalid, // no trap
|
||||
tval: 0,
|
||||
tval: 0,
|
||||
// default values of FullResult
|
||||
ppc_vaddr_csrData: PPC (setAddr(almightyCap, ppc).value), // default use PPC
|
||||
fflags: 0,
|
||||
@@ -700,7 +700,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
regs_ready: regs_ready_aggr // mem currently recv bypass
|
||||
});
|
||||
end
|
||||
doAssert(ppc == fallthrough_pc, "Mem next PC is not PC+4/PC+2");
|
||||
doAssert(ppc == fallthrough_pc, "Mem next PC is not PC+4/PC+2");
|
||||
doAssert(!isValid(dInst.csr), "Mem never explicitly read/write CSR");
|
||||
doAssert((dInst.iType != Fence) == isValid(dInst.imm),
|
||||
"Mem (non-Fence) needs imm for virtual addr");
|
||||
@@ -728,13 +728,13 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
end
|
||||
RobInstState rob_inst_state = NotDone; // mem inst always needs execution
|
||||
let y = ToReorderBuffer{pc: pc,
|
||||
orig_inst: orig_inst,
|
||||
orig_inst: orig_inst,
|
||||
iType: dInst.iType,
|
||||
dst: arch_regs.dst,
|
||||
dst_data: ?, // Available only after execution
|
||||
dst: arch_regs.dst,
|
||||
dst_data: ?, // Available only after execution
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
store_data: ?,
|
||||
store_data_BE: ?,
|
||||
store_data: ?,
|
||||
store_data_BE: ?,
|
||||
`endif
|
||||
csr: dInst.csr,
|
||||
claimed_phy_reg: True, // XXX we always claim a free reg in rename
|
||||
@@ -853,7 +853,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
if(!stop && fetchStage.pipelines[i].canDeq) begin
|
||||
let x = fetchStage.pipelines[i].first; // don't deq now, inst may not have resource
|
||||
let pc = x.pc;
|
||||
let orig_inst = x.orig_inst;
|
||||
let orig_inst = x.orig_inst;
|
||||
let ppc = x.ppc;
|
||||
let main_epoch = x.main_epoch;
|
||||
let dpTrain = x.dpTrain;
|
||||
@@ -865,10 +865,10 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
Addr fallthrough_pc = ((orig_inst[1:0] == 2'b11) ? pc + 4 : pc + 2);
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
if ((i != 0) && (csrf.dcsr_step_bit == 1'b1)) begin
|
||||
stop = True;
|
||||
debug_step = True;
|
||||
end
|
||||
if ((i != 0) && (csrf.dcsr_step_bit == 1'b1)) begin
|
||||
stop = True;
|
||||
debug_step = True;
|
||||
end
|
||||
`endif
|
||||
|
||||
// check for wrong path, if wrong path, don't process it, leave to the other rule in next cycle
|
||||
@@ -1092,13 +1092,13 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
RobInstState rob_inst_state = (to_exec || to_mem || to_FpuMulDiv) ? NotDone : Executed;
|
||||
|
||||
let y = ToReorderBuffer{pc: pc,
|
||||
orig_inst: orig_inst,
|
||||
orig_inst: orig_inst,
|
||||
iType: dInst.iType,
|
||||
dst: arch_regs.dst,
|
||||
dst_data: ?, // Available only after execution
|
||||
dst: arch_regs.dst,
|
||||
dst_data: ?, // Available only after execution
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
store_data: ?,
|
||||
store_data_BE: ?,
|
||||
store_data: ?,
|
||||
store_data_BE: ?,
|
||||
`endif
|
||||
csr: dInst.csr,
|
||||
claimed_phy_reg: True, // XXX we always claim a free reg in rename
|
||||
@@ -1138,7 +1138,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
if (debug_step)
|
||||
rg_m_halt_req <= tagged Valid DebugStep;
|
||||
rg_m_halt_req <= tagged Valid DebugStep;
|
||||
`endif
|
||||
|
||||
// only fire this rule if we make some progress
|
||||
@@ -1186,13 +1186,13 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
method Action debug_halt_req () if (rg_m_halt_req == tagged Invalid);
|
||||
rg_m_halt_req <= tagged Valid DebugHalt;
|
||||
if (verbosity >= 1)
|
||||
$display ("%0d: %m.renameStage.renameStage.debug_halt_req", cur_cycle);
|
||||
$display ("%0d: %m.renameStage.renameStage.debug_halt_req", cur_cycle);
|
||||
endmethod
|
||||
|
||||
method Action debug_resume;
|
||||
rg_m_halt_req <= tagged Invalid;
|
||||
if (verbosity >= 1)
|
||||
$display ("%0d: %m.renameStage.renameStage.debug_resume", cur_cycle);
|
||||
$display ("%0d: %m.renameStage.renameStage.debug_resume", cur_cycle);
|
||||
endmethod
|
||||
`endif
|
||||
|
||||
|
||||
@@ -628,10 +628,10 @@ module mkL2Tlb(L2Tlb::L2Tlb);
|
||||
transCache.addEntry(cRq.vpn, walkLevel, pte.ppn, vm_info.asid);
|
||||
end
|
||||
end
|
||||
else if (! isPpnAligned (pte.ppn, walkLevel)) begin
|
||||
// Leaf page, but PPN is not aligne
|
||||
pageFault("PPN is not aligned");
|
||||
end
|
||||
else if (! isPpnAligned (pte.ppn, walkLevel)) begin
|
||||
// Leaf page, but PPN is not aligne
|
||||
pageFault("PPN is not aligned");
|
||||
end
|
||||
else begin
|
||||
// leaf page, get new entry
|
||||
Vpn masked_vpn = getMaskedVpn(cRq.vpn, walkLevel);
|
||||
|
||||
@@ -93,10 +93,10 @@ typedef union tagged {
|
||||
// Help functions for read-modify-writes of 4-Byte values on a 64-Byte Cache Line
|
||||
|
||||
typedef enum {CACHELINE_CACHE_INVALID,
|
||||
CACHELINE_CACHE_WRITING_BACK,
|
||||
CACHELINE_CACHE_RELOADING,
|
||||
CACHELINE_CACHE_CLEAN,
|
||||
CACHELINE_CACHE_DIRTY
|
||||
CACHELINE_CACHE_WRITING_BACK,
|
||||
CACHELINE_CACHE_RELOADING,
|
||||
CACHELINE_CACHE_CLEAN,
|
||||
CACHELINE_CACHE_DIRTY
|
||||
} Cacheline_Cache_State
|
||||
deriving (Bits, Eq, FShow);
|
||||
|
||||
@@ -154,9 +154,9 @@ module mkLLCDmaConnect #(
|
||||
|
||||
// Respond to store-requests from the external client on store-hit
|
||||
rule rl_handle_MemLoader_st_req ( ( (rg_cacheline_cache_state == CACHELINE_CACHE_CLEAN)
|
||||
|| (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY))
|
||||
&& (fn_addr_is_in_line (axi4_slave_xactor.o_wr_addr.first.awaddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
|| (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY))
|
||||
&& (fn_addr_is_in_line (axi4_slave_xactor.o_wr_addr.first.awaddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
let wr_addr <- pop_o (axi4_slave_xactor.o_wr_addr);
|
||||
let wr_data <- pop_o (axi4_slave_xactor.o_wr_data);
|
||||
Addr addr = wr_addr.awaddr;
|
||||
@@ -178,15 +178,15 @@ module mkLLCDmaConnect #(
|
||||
// Send response to external client
|
||||
AXI4_Wr_Resp #(Wd_Id, Wd_User)
|
||||
wr_resp = AXI4_Wr_Resp {bid: 0, // TODO: change uniformly to Fabric_id
|
||||
bresp: axi4_resp_okay,
|
||||
buser: ?};
|
||||
bresp: axi4_resp_okay,
|
||||
buser: ?};
|
||||
axi4_slave_xactor.i_wr_resp.enq (wr_resp);
|
||||
|
||||
if (verbosity >= 2) begin
|
||||
$display ("%0d: %m.rl_handle_MemLoader_st_req: addr %0h data %0h strb %0h",
|
||||
cur_cycle, wr_addr.awaddr, wr_data.wdata, wr_data.wstrb);
|
||||
$display (" old_dword: %0h", old_dword);
|
||||
$display (" new_dword: %0h", old_dword);
|
||||
cur_cycle, wr_addr.awaddr, wr_data.wdata, wr_data.wstrb);
|
||||
$display (" old_dword: %0h", old_dword);
|
||||
$display (" new_dword: %0h", old_dword);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -195,9 +195,9 @@ module mkLLCDmaConnect #(
|
||||
|
||||
// Responds to load-requests from the external client on load-hit
|
||||
rule rl_handle_MemLoader_ld_req ( ( (rg_cacheline_cache_state == CACHELINE_CACHE_CLEAN)
|
||||
|| (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY))
|
||||
&& (fn_addr_is_in_line (axi4_slave_xactor.o_rd_addr.first.araddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
|| (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY))
|
||||
&& (fn_addr_is_in_line (axi4_slave_xactor.o_rd_addr.first.araddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
let rd_addr <- pop_o (axi4_slave_xactor.o_rd_addr);
|
||||
Addr addr = rd_addr.araddr;
|
||||
|
||||
@@ -209,15 +209,15 @@ module mkLLCDmaConnect #(
|
||||
// Send response to external client
|
||||
AXI4_Rd_Data #(Wd_Id, Wd_Data, Wd_User)
|
||||
rd_data = AXI4_Rd_Data {rid: 0, // TODO: fixup
|
||||
rdata: dword,
|
||||
rresp: axi4_resp_okay,
|
||||
rlast: True,
|
||||
ruser: ?};
|
||||
rdata: dword,
|
||||
rresp: axi4_resp_okay,
|
||||
rlast: True,
|
||||
ruser: ?};
|
||||
axi4_slave_xactor.i_rd_data.enq (rd_data);
|
||||
|
||||
if (verbosity >= 2) begin
|
||||
$display ("%0d: %m.rl_handle_MemLoader_ld_req: addr %0h", cur_cycle, rd_addr.araddr);
|
||||
$display (" dword: %0h", dword);
|
||||
$display (" dword: %0h", dword);
|
||||
end
|
||||
endrule
|
||||
|
||||
@@ -226,29 +226,29 @@ module mkLLCDmaConnect #(
|
||||
|
||||
// Maintain dirty delay countdown
|
||||
rule rl_cacheline_cache_writeback_dirty_delay ( (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY)
|
||||
&& (rg_cacheline_cache_dirty_delay != 0));
|
||||
&& (rg_cacheline_cache_dirty_delay != 0));
|
||||
rg_cacheline_cache_dirty_delay <= rg_cacheline_cache_dirty_delay - 1;
|
||||
endrule
|
||||
|
||||
function Action fa_writeback;
|
||||
action
|
||||
dmaRqT req = DmaRq {addr: rg_cacheline_cache_addr,
|
||||
byteEn: replicate (True), // Write all bytes
|
||||
data: rg_cacheline_cache_data,
|
||||
id: tagged MemLoader (?) // TODO: use wr_addr.awid?
|
||||
};
|
||||
llc.memReq.enq (req);
|
||||
// $display ("%0d: %m.fa_writeback line at %0h", cur_cycle, rg_cacheline_cache_addr);
|
||||
// $display (" data %0128h", rg_cacheline_cache_data);
|
||||
dmaRqT req = DmaRq {addr: rg_cacheline_cache_addr,
|
||||
byteEn: replicate (True), // Write all bytes
|
||||
data: rg_cacheline_cache_data,
|
||||
id: tagged MemLoader (?) // TODO: use wr_addr.awid?
|
||||
};
|
||||
llc.memReq.enq (req);
|
||||
// $display ("%0d: %m.fa_writeback line at %0h", cur_cycle, rg_cacheline_cache_addr);
|
||||
// $display (" data %0128h", rg_cacheline_cache_data);
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
// Initiate writeback if dirty for full delay
|
||||
rule rl_cacheline_cache_writeback_dirty_aged ( (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY)
|
||||
&& (rg_cacheline_cache_dirty_delay == 0));
|
||||
&& (rg_cacheline_cache_dirty_delay == 0));
|
||||
if (verbosity >= 2) begin
|
||||
$display ("%0d: %m.rl_cacheline_cache_writeback_dirty_aged.", cur_cycle);
|
||||
$display (" Old line addr %0h", rg_cacheline_cache_addr);
|
||||
$display ("%0d: %m.rl_cacheline_cache_writeback_dirty_aged.", cur_cycle);
|
||||
$display (" Old line addr %0h", rg_cacheline_cache_addr);
|
||||
end
|
||||
|
||||
fa_writeback;
|
||||
@@ -257,12 +257,12 @@ module mkLLCDmaConnect #(
|
||||
|
||||
// Initiate writeback if dirty and next request is store-miss
|
||||
rule rl_cacheline_cache_writeback_st_miss ( (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY)
|
||||
&& (! fn_addr_is_in_line (axi4_slave_xactor.o_wr_addr.first.awaddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
&& (! fn_addr_is_in_line (axi4_slave_xactor.o_wr_addr.first.awaddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
if (verbosity >= 2) begin
|
||||
$display ("%0d: %m.rl_cacheline_cache_writeback_st_miss.", cur_cycle);
|
||||
$display (" Old line addr %0h", rg_cacheline_cache_addr);
|
||||
$display (" New addr %0h", axi4_slave_xactor.o_wr_addr.first.awaddr);
|
||||
$display ("%0d: %m.rl_cacheline_cache_writeback_st_miss.", cur_cycle);
|
||||
$display (" Old line addr %0h", rg_cacheline_cache_addr);
|
||||
$display (" New addr %0h", axi4_slave_xactor.o_wr_addr.first.awaddr);
|
||||
end
|
||||
|
||||
fa_writeback;
|
||||
@@ -271,12 +271,12 @@ module mkLLCDmaConnect #(
|
||||
|
||||
// Initiate writeback if dirty and next request is load-miss
|
||||
rule rl_cacheline_cache_writeback_ld_miss ( (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY)
|
||||
&& (! fn_addr_is_in_line (axi4_slave_xactor.o_rd_addr.first.araddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
&& (! fn_addr_is_in_line (axi4_slave_xactor.o_rd_addr.first.araddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
if (verbosity >= 2) begin
|
||||
$display ("%0d: %m.rl_cacheline_cache_writeback_ld_miss.", cur_cycle);
|
||||
$display (" Old line addr %0h", rg_cacheline_cache_addr);
|
||||
$display (" New addr %0h", axi4_slave_xactor.o_wr_addr.first.awaddr);
|
||||
$display ("%0d: %m.rl_cacheline_cache_writeback_ld_miss.", cur_cycle);
|
||||
$display (" Old line addr %0h", rg_cacheline_cache_addr);
|
||||
$display (" New addr %0h", axi4_slave_xactor.o_wr_addr.first.awaddr);
|
||||
end
|
||||
|
||||
fa_writeback;
|
||||
@@ -285,42 +285,42 @@ module mkLLCDmaConnect #(
|
||||
|
||||
// Finish writeback
|
||||
rule rl_cacheline_cache_writeback_finish (llc.respSt.first matches tagged MemLoader .id
|
||||
&&& (rg_cacheline_cache_state == CACHELINE_CACHE_WRITING_BACK));
|
||||
&&& (rg_cacheline_cache_state == CACHELINE_CACHE_WRITING_BACK));
|
||||
let resp = llc.respSt.first;
|
||||
llc.respSt.deq;
|
||||
rg_cacheline_cache_state <= CACHELINE_CACHE_CLEAN;
|
||||
|
||||
if (verbosity >= 2) begin
|
||||
$display ("%0d: %m.rl_cacheline_cache_writeback_finish. Line addr %0h",
|
||||
cur_cycle, rg_cacheline_cache_addr);
|
||||
$display (" Line data %0h", rg_cacheline_cache_data);
|
||||
$display ("%0d: %m.rl_cacheline_cache_writeback_finish. Line addr %0h",
|
||||
cur_cycle, rg_cacheline_cache_addr);
|
||||
$display (" Line data %0h", rg_cacheline_cache_data);
|
||||
end
|
||||
endrule
|
||||
|
||||
function Action fa_initiate_reload (Addr addr);
|
||||
action
|
||||
let line_addr = fn_align_addr_to_line (addr);
|
||||
dmaRqT req = DmaRq {addr: line_addr,
|
||||
byteEn: replicate (False), // all False means 'read'
|
||||
data: ?,
|
||||
id: tagged MemLoader (?)}; // TODO: change uniformly to wr_addr.awid
|
||||
llc.memReq.enq (req);
|
||||
rg_cacheline_cache_addr <= line_addr;
|
||||
let line_addr = fn_align_addr_to_line (addr);
|
||||
dmaRqT req = DmaRq {addr: line_addr,
|
||||
byteEn: replicate (False), // all False means 'read'
|
||||
data: ?,
|
||||
id: tagged MemLoader (?)}; // TODO: change uniformly to wr_addr.awid
|
||||
llc.memReq.enq (req);
|
||||
rg_cacheline_cache_addr <= line_addr;
|
||||
|
||||
if (verbosity >= 2) begin
|
||||
$display (" fa_initiate_reload: line_addr %0h", line_addr);
|
||||
end
|
||||
if (verbosity >= 2) begin
|
||||
$display (" fa_initiate_reload: line_addr %0h", line_addr);
|
||||
end
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
// Initiate reload when cacheline_cache is clean on store-miss
|
||||
rule rl_cacheline_cache_reload_req_st ( (rg_cacheline_cache_state == CACHELINE_CACHE_CLEAN)
|
||||
&& (! fn_addr_is_in_line (axi4_slave_xactor.o_wr_addr.first.awaddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
&& (! fn_addr_is_in_line (axi4_slave_xactor.o_wr_addr.first.awaddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
let addr = axi4_slave_xactor.o_wr_addr.first.awaddr;
|
||||
|
||||
if (verbosity >= 2) begin
|
||||
$display ("%0d: %m.rl_cacheline_cache_reload_req_st for addr %0h", cur_cycle, addr);
|
||||
$display ("%0d: %m.rl_cacheline_cache_reload_req_st for addr %0h", cur_cycle, addr);
|
||||
end
|
||||
|
||||
fa_initiate_reload (addr);
|
||||
@@ -329,12 +329,12 @@ module mkLLCDmaConnect #(
|
||||
|
||||
// Initiate reload when cacheline_cache is clean on load-miss
|
||||
rule rl_cacheline_cache_reload_req_ld ( (rg_cacheline_cache_state == CACHELINE_CACHE_CLEAN)
|
||||
&& (! fn_addr_is_in_line (axi4_slave_xactor.o_rd_addr.first.araddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
&& (! fn_addr_is_in_line (axi4_slave_xactor.o_rd_addr.first.araddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
let addr = axi4_slave_xactor.o_rd_addr.first.araddr;
|
||||
|
||||
if (verbosity >= 2) begin
|
||||
$display ("%0d: %m.rl_cacheline_cache_reload_req_ld for addr %0h", cur_cycle, addr);
|
||||
$display ("%0d: %m.rl_cacheline_cache_reload_req_ld for addr %0h", cur_cycle, addr);
|
||||
end
|
||||
|
||||
fa_initiate_reload (addr);
|
||||
@@ -343,15 +343,15 @@ module mkLLCDmaConnect #(
|
||||
|
||||
// Finish reload
|
||||
rule rl_cacheline_cache_reload_finish (llc.respLd.first.id matches tagged MemLoader .id
|
||||
&&& (rg_cacheline_cache_state == CACHELINE_CACHE_RELOADING));
|
||||
&&& (rg_cacheline_cache_state == CACHELINE_CACHE_RELOADING));
|
||||
let resp = llc.respLd.first;
|
||||
llc.respLd.deq;
|
||||
rg_cacheline_cache_state <= CACHELINE_CACHE_CLEAN;
|
||||
rg_cacheline_cache_data <= resp.data;
|
||||
|
||||
if (verbosity >= 2) begin
|
||||
$display ("%0d: %m.rl_cacheline_cache_reload_finish. Line addr %0h", cur_cycle, rg_cacheline_cache_addr);
|
||||
$display (" Line data %0h", resp.data);
|
||||
$display ("%0d: %m.rl_cacheline_cache_reload_finish. Line addr %0h", cur_cycle, rg_cacheline_cache_addr);
|
||||
$display (" Line data %0h", resp.data);
|
||||
end
|
||||
endrule
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ DataAlignedAddr mainMemBaseAddr = getDataAlignedAddr(soc_map_struct.main_mem_a
|
||||
// upper bound addr (bound itself is invalid addr) for each MMIO reg/device
|
||||
// (aligned to Data)
|
||||
DataAlignedAddr mainMemBoundAddr = (mainMemBaseAddr +
|
||||
getDataAlignedAddr(soc_map_struct.main_mem_addr_size));
|
||||
getDataAlignedAddr(soc_map_struct.main_mem_addr_size));
|
||||
DataAlignedAddr msipBoundAddr = msipBaseAddr +
|
||||
fromInteger(valueof(TDiv#(CoreNum, 2)));
|
||||
DataAlignedAddr mtimecmpBoundAddr = mtimecmpBaseAddr +
|
||||
|
||||
@@ -271,7 +271,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
);
|
||||
// inst is done
|
||||
rob_inst_state[state_finishAlu_port(i)] <= Executed;
|
||||
// Destination register data, for Tandem Verification
|
||||
// Destination register data, for Tandem Verification
|
||||
rg_dst_data <= dst_data;
|
||||
|
||||
// update PPC or csrData (vaddr is always useless for ALU results)
|
||||
@@ -296,7 +296,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
method Action set(Data dst_data, Bit#(5) new_fflags);
|
||||
// inst is done
|
||||
rob_inst_state[state_finishFpuMulDiv_port(i)] <= Executed;
|
||||
rg_dst_data <= dst_data;
|
||||
rg_dst_data <= dst_data;
|
||||
// update fflags
|
||||
fflags[fflags_finishFpuMulDiv_port(i)] <= new_fflags;
|
||||
endmethod
|
||||
@@ -312,8 +312,8 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
interface setExecuted_doFinishFpuMulDiv = fpuMulDivExe;
|
||||
|
||||
method Action setExecuted_doFinishMem(Addr vaddr,
|
||||
Data store_data, ByteEn store_data_BE,
|
||||
Bool access_at_commit, Bool non_mmio_st_done
|
||||
Data store_data, ByteEn store_data_BE,
|
||||
Bool access_at_commit, Bool non_mmio_st_done
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
@@ -403,13 +403,13 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
method ToReorderBuffer read_deq;
|
||||
return ToReorderBuffer {
|
||||
pc: pc,
|
||||
orig_inst: orig_inst,
|
||||
orig_inst: orig_inst,
|
||||
iType: iType,
|
||||
dst: rg_dst_reg,
|
||||
dst_data: rg_dst_data,
|
||||
dst: rg_dst_reg,
|
||||
dst_data: rg_dst_data,
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
store_data: rg_store_data,
|
||||
store_data_BE: rg_store_data_BE,
|
||||
store_data: rg_store_data,
|
||||
store_data_BE: rg_store_data_BE,
|
||||
`endif
|
||||
csr: csr,
|
||||
claimed_phy_reg: claimed_phy_reg,
|
||||
@@ -464,7 +464,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
doAssert(!isValid(trap[trap_deqLSQ_port]), "cannot have trap");
|
||||
if(cause matches tagged Valid .e) begin
|
||||
trap[trap_deqLSQ_port] <= Valid (Exception (e));
|
||||
// TODO: shouldn't we record tval here as well?
|
||||
// TODO: shouldn't we record tval here as well?
|
||||
end
|
||||
// record ld misspeculation
|
||||
ldKilled[ldKill_deqLSQ_port] <= ld_killed;
|
||||
@@ -566,9 +566,9 @@ interface SupReorderBuffer#(numeric type aluExeNum, numeric type fpuMulDivExeNum
|
||||
interface Vector#(fpuMulDivExeNum, ROB_setExecuted_doFinishFpuMulDiv) setExecuted_doFinishFpuMulDiv;
|
||||
// doFinishMem, after addr translation
|
||||
method Action setExecuted_doFinishMem(InstTag x,
|
||||
Addr vaddr,
|
||||
Data store_data, ByteEn store_data_BE,
|
||||
Bool access_at_commit, Bool non_mmio_st_done
|
||||
Addr vaddr,
|
||||
Data store_data, ByteEn store_data_BE,
|
||||
Bool access_at_commit, Bool non_mmio_st_done
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
`endif
|
||||
@@ -850,7 +850,7 @@ module mkSupReorderBuffer#(
|
||||
function Bool getDepOn(Integer i) = row[w][i].dependsOn_wrongSpec(specTag);
|
||||
depVec[w] = map(getDepOn, genVector);
|
||||
end
|
||||
if (verbose)
|
||||
if (verbose)
|
||||
$display("[ROB incorrectSpec] ",
|
||||
fshow(specTag), " ; ",
|
||||
fshow(killInstTag), " ; ",
|
||||
|
||||
@@ -1979,7 +1979,7 @@ module mkSplitLSQ(SplitLSQ);
|
||||
wrongPath: False,
|
||||
dst: Invalid,
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
instTag: ld_instTag [t], // For recording Ld data in ROB
|
||||
instTag: ld_instTag [t], // For recording Ld data in ROB
|
||||
`endif
|
||||
data: ?
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user