playground/bsv/hack.bsv

132 lines
2.7 KiB
Plaintext

/*
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