/* https://github.com/rsnikhil/RISCV_ISA_Formal_Spec_in_BSV/blob/master/RISCV_Spec/RISCV_Spec.bsv https://github.com/rsnikhil/RISCV_ISA_Formal_Spec_in_BSV/blob/master/RISCV_Spec/ISA_Decls.bsv */ package Instr; import Ainstr :: *; import Cinstr :: *; /* typedef Bit#(16) Instr; */ typedef struct { Bit#(1) ac; union tagged { Ainstr::T; Cinstr::T; } } T deriving Bits; endpackage: Instr package Ainstr; typedef struct { Bit#(15) loc; } T deriving Bits; function Bit#(15) loc(T ai) = ai::loc; endpackage: Ainstr package Cinstr; typedef struct { Bit#(1) zx; Bit#(1) nx; Bit#(1) zy; Bit#(1) ny; Bit#(1) f; Bit#(1) no; } Comp deriving Bits; // Fields of C-instruction typedef Bit#(1) A; // `a' value typedef Bit#(3) Dest; // Destination register typedef Bit#(3) Jump; // Jump target typedef struct { Reserved#(2) dummy; // unused bits Instr::A a; Instr::Comp comp; Instr::Dest dest; Instr::Jump jump; } T deriving Bits; function A a(T ci) = ci::a; function Comp comp(T ci) = ci::comp; function Dest dest(T ci) = ci::dest; function Jump jump(T ci) = ci::jump; /* function A a(T i) = i[12]; */ /* function Comp comp(T i) = i[11:6]; */ /* function Dest dest(T i) = i[5:3]; */ /* function Jump jump(T i) = i[2:0]; */ // A -> Comp -> /* function Instr encode(A a, Comp c, Dest d, Jump j); */ endpackage: cinstr package hack; // ALU function Tuple3#(Bit#(16), // out Bit#(1), // zr: Set if out is zero Bit#(1)) // ng: Set if out is negative alu(Bit#(16) x, Bit#(16) y, Bit#(1) zx, // Zero x input Bit#(1) nx, // Negate x input Bit#(1) zy, // Zero y input Bit#(1) ny, // Negate y input Bit#(1) f, // x+y if set, else x&&y Bit#(1) no); // Negate out value Bit#(16) out=0; Bit#(1) zr=0; Bit#(1) ng=0; if(zx) x=0; if(nx) x=!x; if(zy) y=0; if(ny) y=!y; if(f) out=x+y; else out=x&y; if(no) out=!out; if(out==0) zr=1; else zr=0; if(out<0) ng=1; else ng=0; return tuple3(out, zr, ng); endfunction import Instr :: *; function Tuple4#(Bit#(16), Bit#(1), Bit#(15), Bit#(15)) alufn(Bit#(16) inM, Bit#(16) instr, Bit#(1) reset); endfunction interface CPU_I; method Action start( Bit#(16) inM, Instr::T instr, Bit#(1) rst // reset ); method #(Bit#(16)) getOutM(); method #(Bit#(1)) getWriteM(); method #(Bit#(15)) getAddrM(); method #(Bit#(15)) getPC(); endinterface: CPU_I module cpu(CPU_I); Reg#(Bit#(16)) PC; Reg#(Bit#(16)) D; Reg#(Bit#(16)) M; method Action start(Bit#(16) inM, Instr::T instr, Bit#(1) rst); endmodule: cpu endpackage: hack