132 lines
2.7 KiB
Plaintext
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
|