Merge branch 'CHERI' into pdr32-wip
This commit is contained in:
@@ -1025,6 +1025,10 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
default: return 0;
|
||||
endcase);
|
||||
end
|
||||
tagged CapException .ce: begin
|
||||
cause_code = pack(CHERIFault);
|
||||
// populate CHERI cause register.
|
||||
end
|
||||
tagged Interrupt .i: begin
|
||||
cause_code = zeroExtend(pack(i));
|
||||
cause_interrupt = 1;
|
||||
|
||||
@@ -53,7 +53,7 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
Bits#(childT, b__),
|
||||
FShow#(ToMemMsg#(idT, childT)),
|
||||
FShow#(MemRsMsg#(idT, childT)),
|
||||
Add#(SizeOf#(Line), 0, 512)); // assert Line sz = 512
|
||||
Add#(SizeOf#(Line), 0, TAdd#(512, 4))); // assert Line sz = 512 + 4 tags
|
||||
|
||||
// Verbosity: 0: quiet; 1: LLC transactions; 2: loop detail
|
||||
Integer verbosity = 0;
|
||||
@@ -141,7 +141,7 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
Reg #(Bit #(3)) rg_rd_rsp_beat <- mkReg (0);
|
||||
|
||||
FIFOF #(LdMemRq #(idT, childT)) f_pending_reads <- mkFIFOF;
|
||||
Reg #(Bit #(512)) rg_cline <- mkRegU;
|
||||
Reg #(CLine) rg_cline <- mkRegU;
|
||||
|
||||
rule rl_handle_read_req (llc.toM.first matches tagged Ld .ld
|
||||
&&& (ctr_wr_rsps_pending.value == 0));
|
||||
@@ -180,11 +180,14 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
end
|
||||
|
||||
// Shift next 64 bits from fabric into the cache line being assembled
|
||||
let new_cline = { mem_rsp.rdata, rg_cline [511:64] };
|
||||
let new_cline_tag = { mem_rsp.ruser, pack(rg_cline.tag) [3:1] };
|
||||
let new_cline_data = { mem_rsp.rdata, pack(rg_cline.data) [511:64] };
|
||||
let new_cline = CLine { tag: rg_rd_rsp_beat[0] == 0 ? unpack(new_cline_tag) : rg_cline.tag
|
||||
, data: unpack(new_cline_data) };
|
||||
|
||||
if (rg_rd_rsp_beat == 7) begin
|
||||
let ldreq <- pop (f_pending_reads);
|
||||
MemRsMsg #(idT, childT) resp = MemRsMsg {data: unpack (new_cline),
|
||||
MemRsMsg #(idT, childT) resp = MemRsMsg {data: new_cline,
|
||||
child: ldreq.child,
|
||||
id: ldreq.id};
|
||||
|
||||
@@ -214,11 +217,11 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
end
|
||||
|
||||
Addr line_addr = { wb.addr [63:6], 6'h0 }; // Addr of containing cache line
|
||||
Line line_data = wb.data;
|
||||
Vector #(8, Bit #(8)) line_bes = unpack (pack (wb.byteEn));
|
||||
Vector #(8, Bit #(64)) line_data = unpack(pack(wb.data.data));
|
||||
|
||||
Addr offset = zeroExtend ( { rg_wr_req_beat, 3'b_000 } ); // Addr offset of 64b word for this beat
|
||||
Bit #(64) data64 = line_data [rg_wr_req_beat];
|
||||
Bit #(64) data64 = line_data[rg_wr_req_beat];
|
||||
Bit #(8) strb8 = line_bes [rg_wr_req_beat];
|
||||
fa_fabric_send_write_req (line_addr | offset, strb8, data64);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// Copyright (c) 2018 Massachusetts Institute of Technology
|
||||
// Portions (c) 2019-2020 Bluespec, Inc.
|
||||
//
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
@@ -9,10 +9,10 @@
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
// of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
@@ -171,7 +171,6 @@ function Bit #(64) fn_amo_op (Bit #(2) sz, // encodes data size (.W or
|
||||
Bit #(64) w1 = fn_extract_and_extend_bytes (sz, addr, ld_val);
|
||||
Bit #(64) w2 = fn_extract_and_extend_bytes (sz, addr, st_val);
|
||||
|
||||
|
||||
// Do AMO op
|
||||
Int #(64) i1 = unpack (w1); // Signed, for signed ops
|
||||
Int #(64) i2 = unpack (w2); // Signed, for signed ops
|
||||
@@ -257,13 +256,13 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
Reg #(CoreId) reqCore <- mkRegU;
|
||||
Reg #(MMIOFunc) reqFunc <- mkRegU;
|
||||
Reg #(AmoFunc) reqAmofunc <- mkRegU;
|
||||
Reg #(ByteEn) reqBE <- mkRegU;
|
||||
Reg #(MemDataByteEn) reqBE <- mkRegU;
|
||||
Reg #(Bit #(2)) reqSz <- mkRegU;
|
||||
Reg #(Data) reqData <- mkRegU;
|
||||
Reg #(MemTaggedData) reqData <- mkRegU;
|
||||
|
||||
// For inst fetch, we need more bookkeepings
|
||||
// offset of the requested inst within a Data
|
||||
Reg#(DataInstOffset) instSel <- mkRegU;
|
||||
Reg#(MemDataInstOffset) instSel <- mkRegU;
|
||||
// the current superscaler way being fetched
|
||||
Reg#(SupWaySel) fetchingWay <- mkRegU;
|
||||
// the already fetched insts
|
||||
@@ -280,7 +279,7 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
|
||||
// in case of AMO on mtime and mtimecmp, resp may be sent after waiting for
|
||||
// CRs, we record the AMO resp at processing time
|
||||
Reg#(Data) amoResp <- mkRegU;
|
||||
Reg#(MemTaggedData) amoResp <- mkRegU;
|
||||
|
||||
// we increment mtime periodically
|
||||
Reg#(Bit#(TLog#(CyclesPerTimeInc))) cycle <- mkReg(0);
|
||||
@@ -474,7 +473,7 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
cores[lower_core].pRq.enq(MMIOPRq {
|
||||
target: MSIP,
|
||||
func: reqFunc,
|
||||
data: truncate(reqData)
|
||||
data: fromMemTaggedData(reqData)
|
||||
});
|
||||
waitLowerMSIPCRs <= Valid (lower_core);
|
||||
waitUpperMSIPCRs <= Invalid;
|
||||
@@ -484,7 +483,7 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
cores[upper_core].pRq.enq(MMIOPRq {
|
||||
target: MSIP,
|
||||
func: reqFunc,
|
||||
data: truncate(reqData)
|
||||
data: fromMemTaggedData(reqData)
|
||||
});
|
||||
waitLowerMSIPCRs <= Valid (upper_core);
|
||||
waitUpperMSIPCRs <= Invalid;
|
||||
@@ -507,14 +506,14 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
cores[lower_core].pRq.enq(MMIOPRq {
|
||||
target: MSIP,
|
||||
func: reqFunc,
|
||||
data: zeroExtend(reqData[0])
|
||||
data: zeroExtend(pack(reqData.data)[0])
|
||||
});
|
||||
end
|
||||
if(upper_en) begin
|
||||
cores[upper_core].pRq.enq(MMIOPRq {
|
||||
target: MSIP,
|
||||
func: reqFunc,
|
||||
data: zeroExtend(reqData[32])
|
||||
data: zeroExtend(pack(reqData.data)[32])
|
||||
});
|
||||
end
|
||||
state <= WaitResp;
|
||||
@@ -542,11 +541,11 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
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: toMemTaggedData({upper_data, lower_data})
|
||||
}));
|
||||
if(verbosity > 0) begin
|
||||
$display("[Platform - msip done] lower %x, upper %x",
|
||||
@@ -557,21 +556,21 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
function Data getWriteData(Data orig);
|
||||
if(reqFunc matches tagged Amo .amoFunc) begin
|
||||
// amo
|
||||
Bool doubleWord = reqBE[4] && reqBE[0];
|
||||
Bool upper32 = reqBE[4] && !reqBE[0];
|
||||
let amoInst = AmoInst {
|
||||
func: amoFunc,
|
||||
doubleWord: doubleWord,
|
||||
width: reqBE[4] && reqBE[0] ? DWord : Word,
|
||||
aq: False,
|
||||
rl: False
|
||||
};
|
||||
return amoExec(amoInst, orig, reqData, upper32);
|
||||
let res = amoExec(amoInst, {0, pack(reqBE[4] && !reqBE[0])},
|
||||
toMemTaggedData(orig), reqData);
|
||||
return res.data[0];
|
||||
end
|
||||
else begin
|
||||
// normal store
|
||||
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
|
||||
Vector#(DataBytes, Bit#(8)) data = unpack(orig);
|
||||
Vector#(DataBytes, Bit#(8)) wrVec = fromMemTaggedData(reqData);
|
||||
for(Integer i = 0; i < valueof(DataBytes); i = i+1) begin
|
||||
if(reqBE[i]) begin
|
||||
data[i] = wrVec[i];
|
||||
end
|
||||
@@ -621,7 +620,7 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
if(reqFunc == Ld) begin
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: True,
|
||||
data: oldMTimeCmp
|
||||
data: toMemTaggedData(oldMTimeCmp)
|
||||
}));
|
||||
state <= SelectReq;
|
||||
if(verbosity > 0) begin
|
||||
@@ -634,7 +633,7 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
let newData = getWriteData(oldMTimeCmp);
|
||||
mtimecmp[offset] <= newData;
|
||||
// get and record amo resp
|
||||
let respData = getAmoResp(oldMTimeCmp);
|
||||
let respData = toMemTaggedData(getAmoResp(oldMTimeCmp));
|
||||
amoResp <= respData;
|
||||
// check changes to MTIP
|
||||
if(newData <= mtime && !mtip[offset]) begin
|
||||
@@ -707,7 +706,7 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
end
|
||||
else if(reqFunc == Ld) begin
|
||||
cores[reqCore].pRs.enq(DataAccess (MMIODataPRs {
|
||||
valid: True, data: mtime
|
||||
valid: True, data: toMemTaggedData(mtime)
|
||||
}));
|
||||
state <= SelectReq;
|
||||
if(verbosity > 0) begin
|
||||
@@ -720,7 +719,7 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
let newData = getWriteData(mtime);
|
||||
mtime <= newData;
|
||||
// get and record AMO resp
|
||||
let respData = getAmoResp(mtime);
|
||||
let respData = toMemTaggedData(getAmoResp(mtime));
|
||||
amoResp <= respData;
|
||||
// check change in MTIP
|
||||
Vector#(CoreNum, Bool) changeMTIP = replicate(False);
|
||||
@@ -809,7 +808,7 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
else if(reqFunc == Ld) begin
|
||||
resp.valid = True;
|
||||
if(toHostQ.notEmpty) begin
|
||||
resp.data = toHostQ.first;
|
||||
resp.data = toMemTaggedData(toHostQ.first);
|
||||
end
|
||||
else begin
|
||||
resp.data = 0;
|
||||
@@ -860,7 +859,7 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
else if(reqFunc == Ld) begin
|
||||
resp.valid = True;
|
||||
if(fromHostQ.notEmpty) begin
|
||||
resp.data = fromHostQ.first;
|
||||
resp.data = toMemTaggedData(fromHostQ.first);
|
||||
end
|
||||
else begin
|
||||
resp.data = 0;
|
||||
@@ -950,10 +949,12 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
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);
|
||||
let new_st_val = fn_amo_op ( reqSz, reqAmofunc, addr
|
||||
, fromMemTaggedData(ld_val)
|
||||
, fromMemTaggedData(reqData));
|
||||
|
||||
// Write back new st_val to fabric
|
||||
let req = MMIOCRq {addr:addr, func:tagged St, byteEn:reqBE, data:new_st_val};
|
||||
let req = MMIOCRq {addr:addr, func:tagged St, byteEn:reqBE, data:toMemTaggedData(new_st_val)};
|
||||
mmio_fabric_adapter_core_side.request.put (req);
|
||||
|
||||
let prs = tagged DataAccess (MMIODataPRs { valid: True, data: ld_val });
|
||||
@@ -1020,7 +1021,6 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
|
||||
else begin
|
||||
// No access fault
|
||||
let data = dprs.data;
|
||||
|
||||
SupWaySel maxWay = 0;
|
||||
if(reqFunc matches tagged Inst .w) begin
|
||||
@@ -1028,7 +1028,7 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
end
|
||||
|
||||
// View Data as a vector of instructions
|
||||
Vector#(DataSzInst, Instruction) instVec = unpack(data);
|
||||
Vector#(MemDataSzInst, Instruction) instVec = fromMemTaggedData(dprs.data);
|
||||
// extract inst from resp data
|
||||
Instruction inst = instVec[instSel];
|
||||
// check whether we are done or not
|
||||
|
||||
@@ -32,6 +32,7 @@ import CreditCounter :: *;
|
||||
// ----------------
|
||||
// From MIT RISCY-OOO
|
||||
|
||||
import Types :: *;
|
||||
import ProcTypes :: *;
|
||||
|
||||
// ----------------
|
||||
@@ -68,6 +69,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
|
||||
FIFOF #(MMIOCRq) f_reqs_from_core <- mkFIFOF;
|
||||
FIFOF #(MMIODataPRs) f_rsps_to_core <- mkFIFOF;
|
||||
Reg#(Fabric_Addr) read_req_addr <- mkRegU;
|
||||
|
||||
SoC_Map_IFC soc_map <- mkSoC_Map; // for m_is_IO_addr
|
||||
|
||||
@@ -99,6 +101,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
aruser: fabric_default_aruser};
|
||||
|
||||
master_xactor.slave.ar.put(mem_req_rd_addr);
|
||||
read_req_addr <= addr;
|
||||
|
||||
// Debugging
|
||||
if (cfg_verbosity > 0) begin
|
||||
@@ -180,7 +183,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
fa_fabric_send_read_req (req.addr);
|
||||
else begin
|
||||
let rsp = MMIODataPRs {valid: False,
|
||||
data: req.addr}; // For debugging convenience only
|
||||
data: toMemTaggedData(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",
|
||||
@@ -194,6 +197,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
|
||||
rule rl_handle_read_rsps;
|
||||
let mem_rsp <- get(master_xactor.slave.r);
|
||||
dynamicAssert(mem_rsp.rlast, "TODO, implement multi-flit transactions");
|
||||
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display ("%0d: %m.rl_handle_read_rsps ", cur_cycle);
|
||||
@@ -205,8 +209,10 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
$display (" ", fshow (mem_rsp));
|
||||
end
|
||||
|
||||
let newData = MemTaggedData { tag: False
|
||||
, data: unpack(zeroExtend(mem_rsp.rdata) << ((read_req_addr[3] == 1) ? 64 : 0))};
|
||||
let rsp = MMIODataPRs {valid: (mem_rsp.rresp == OKAY),
|
||||
data: mem_rsp.rdata};
|
||||
data: newData };
|
||||
f_rsps_to_core.enq (rsp);
|
||||
|
||||
if (cfg_verbosity > 0)
|
||||
@@ -227,11 +233,12 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
// 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.
|
||||
dynamicAssert(pack(req.byteEn)[15:8] == 0, "TODO, handle multiflit transactions");
|
||||
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, truncate(pack(req.byteEn)), fromMemTaggedData(req.data));
|
||||
else begin
|
||||
let rsp = MMIODataPRs {valid: False,
|
||||
data: req.addr}; // For debugging convenience only
|
||||
data: toMemTaggedData(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",
|
||||
|
||||
Reference in New Issue
Block a user