120 lines
3.3 KiB
Plaintext
120 lines
3.3 KiB
Plaintext
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
// Copyright (C) 2022 Sergiusz Bazanski
|
|
|
|
package CPU_RegisterFile;
|
|
|
|
import ConfigReg :: *;
|
|
import Vector :: *;
|
|
|
|
import CPU_Defs :: *;
|
|
|
|
interface CPU_RegisterFile;
|
|
interface RegisterRead fetchRead;
|
|
|
|
interface RegisterRead computeSource1;
|
|
interface RegisterRead computeSource2;
|
|
interface StatusWordRead computeStatusSource;
|
|
interface RegisterWriteCompute computeWrite;
|
|
interface RegisterWriteMemory memoryWrite;
|
|
endinterface
|
|
|
|
module mkConstantReg #(Word val)
|
|
(Reg#(Word));
|
|
method Word _read;
|
|
return val;
|
|
endmethod
|
|
method Action _write(Word w);
|
|
endmethod
|
|
endmodule
|
|
|
|
(* synthesize *)
|
|
module mkRFReg(Reg#(Word));
|
|
let res <- mkConfigReg(0);
|
|
return res;
|
|
endmodule
|
|
|
|
typedef Wire#(Tuple2#(Register, Word)) WriteReq;
|
|
|
|
(* synthesize *)
|
|
module mkCPURegisterFile(CPU_RegisterFile);
|
|
function m#(Reg#(Word)) makeRegs(Integer ix) provisos (IsModule#(m, c));
|
|
return case (ix) matches
|
|
0: mkConstantReg(32'h00000000);
|
|
1: mkConstantReg(32'hFFFFFFFF);
|
|
2: mkConstantReg(32'hDEADBEEF);
|
|
4: mkConfigReg(32'h20002000);
|
|
default: mkRFReg;
|
|
endcase;
|
|
endfunction
|
|
Vector#(32, Reg#(Word)) regs <- genWithM(makeRegs);
|
|
Reg#(Word) status <- mkReg(0);
|
|
|
|
WriteReq writeReqCompute <- mkWire;
|
|
WriteReq writeReqMemory <- mkWire;
|
|
|
|
Vector #(2, WriteReq) writeReqs;
|
|
writeReqs[0] = writeReqCompute;
|
|
writeReqs[1] = writeReqMemory;
|
|
|
|
|
|
Vector #(29, Register) writableRegisters;
|
|
for (Integer i = 0; i < 29; i = i + 1) begin
|
|
Bit#(32) no = fromInteger(i + 3);
|
|
writableRegisters[i] = unpack(no[4:0]);
|
|
end
|
|
|
|
function Rules genRegRules(Register regno);
|
|
function Rules genRegRule(WriteReq wr);
|
|
return (rules
|
|
rule foo if (tpl_1(wr) == regno);
|
|
regs[pack(regno)] <= tpl_2(wr);
|
|
endrule
|
|
endrules);
|
|
endfunction
|
|
return foldl1(rJoinPreempts, map(genRegRule, writeReqs));
|
|
endfunction
|
|
addRules(joinRules(map(genRegRules, writableRegisters)));
|
|
|
|
function RegisterRead makeRead();
|
|
return (interface RegisterRead;
|
|
method Word read(Register ix);
|
|
return regs[pack(ix)];
|
|
endmethod
|
|
endinterface);
|
|
endfunction
|
|
|
|
interface RegisterRead fetchRead = makeRead;
|
|
interface RegisterRead computeSource1 = makeRead;
|
|
interface RegisterRead computeSource2 = makeRead;
|
|
interface StatusWordRead computeStatusSource;
|
|
method StatusWord read = unpack(status);
|
|
endinterface
|
|
|
|
interface RegisterWriteCompute computeWrite;
|
|
method Action write( Maybe#(StatusWord) sw
|
|
, Maybe#(Tuple2#(Register, Word)) rd
|
|
);
|
|
|
|
case (sw) matches
|
|
tagged Valid .swd: begin
|
|
status <= pack(swd);
|
|
end
|
|
endcase
|
|
case (rd) matches
|
|
tagged Valid .rdd: begin
|
|
writeReqCompute <= rdd;
|
|
end
|
|
endcase
|
|
endmethod
|
|
endinterface
|
|
|
|
interface RegisterWriteMemory memoryWrite;
|
|
method Action write(Register rd, Word value);
|
|
writeReqMemory <= tuple2(rd, value);
|
|
endmethod
|
|
endinterface
|
|
endmodule
|
|
|
|
|
|
endpackage
|