Merge branch 'CHERI' into pdr32-wip

This commit is contained in:
Peter Rugg
2020-05-11 14:08:42 +01:00
36 changed files with 928 additions and 587 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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",