123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- MODULE RISC5 (IN clk, rst, stallX: BIT; (*NW 18.9.2016*)
- IN inbus, codebus: WORD;
- OUT adr: [24] BIT;
- rd, wr, ben: BIT;
- outbus: WORD);
-
- CONST StartAdr = 3FF800H'22;
- TYPE PROM := MODULE (IN clk: BIT;
- IN adr: [9] BIT;
- OUT data: WORD) ^;
-
- Multiplier := MODULE (IN clk, run, u: BIT;
- OUT stall: BIT;
- IN x, y: WORD;
- OUT z: [64] BIT) ^;
- Divider := MODULE (IN clk, run, u: BIT;
- OUT stall: BIT;
- IN x, y: WORD;
- OUT quot, rem: WORD) ^;
- FPAdder := MODULE (IN clk, run, u, v: BIT; OUT stall: BIT;
- IN x, y: WORD; OUT z: WORD) ^;
- FPMultiplier := MODULE (IN clk, run: BIT; OUT stall: BIT;
- IN x, y: WORD; OUT z: WORD) ^;
- FPDivider := MODULE (IN clk, run: BIT; OUT stall: BIT;
- IN x, y: WORD; OUT z: WORD) ^;
- REG (clk) PC: [22] BIT; (*program counter*)
- IR: WORD; (*instruction register*)
- N, Z, C, OV: BIT; (*condition flags*)
- stall1, PMsel: BIT;
- R: [16] WORD; (*data registers*)
- H: WORD; (*auxiliary register*)
- VAR PM: PROM; (*mem for boot loader*)
- mulUnit: Multiplier;
- divUnit: Divider;
- faddUnit: FPAdder;
- fmulUnit: FPMultiplier;
- fdivUnit: FPDivider;
- pcmux, nxpc: [22] BIT;
- cond, S: BIT;
- sa, sb, sc: BIT;
- ins, pmout: WORD;
- p, q, u, v, w: BIT; (*instruction fields*)
- op, ira, ira0, irb, irc: [4] BIT;
- cc: [3] BIT;
- imm: [16] BIT;
- off: [20] BIT;
- offL: [24] BIT;
- regwr, stall, stallL, stallM, stallD, stallFA, stallFM, stallFD: BIT;
- sc1, sc0: [2] BIT; (*shift counts*)
- a0, a1, a2, a3: BIT;
- inbusL, outbusB0, outbusB1, outbusB2, outbusB3: BYTE;
- inbusH: [24] BIT;
- A, B, C0, C1, aluRes, regmux: WORD;
- s1, s2, s3, t1, t2, t3: WORD; (*shifting*)
- quotient, remainder: WORD;
- product: [64] BIT;
- fsum, fprod, fquot: WORD;
- Add, Sub, Mul, Div: BIT;
- Fadd, Fsub, Fmul, Fdiv: BIT;
- Ldr, Str, Br: BIT;
- BEGIN PM(clk, pcmux[8:0], pmout);
- mulUnit (clk, Mul, ~u, stallM, B, C1, product);
- divUnit (clk, Div, ~u, stallD, B, C1, quotient, remainder);
- faddUnit (clk, Fadd|Fsub, u, v, stallFA, B, {Fsub^C0.31, C0[30:0]}, fsum);
- fmulUnit (clk, Fmul, stallFM, B, C0, fprod);
- fdivUnit (clk, Fdiv, stallFD, B, C0, fquot);
- ins := PMsel -> pmout : IR; (*current instruction*)
- p := ins.31; (*instruction fields*)
- q := ins.30;
- u := ins.29;
- v := ins.28;
- w := ins.16;
- cc:= ins[26:24];
- ira := ins[27:24];
- irb := ins[23:20];
- op := ins[19:16];
- irc := ins[3:0];
- imm := ins[15:0]; (*reg instr*)
- off := ins[19:0]; (*mem instr*)
- offL := ins[23:0]; (*branch instr*)
- Add := ~p & (op = 8);
- Sub := ~p & (op = 9);
- Mul := ~p & (op = 10);
- Div := ~p & (op = 11);
- Fadd := ~p & (op = 12);
- Fsub := ~p & (op = 13);
- Fmul := ~p & (op = 14);
- Fdiv := ~p & (op = 15);
- Ldr := p & ~q & ~u;
- Str := p & ~q & u;
- Br := p & q;
- (*ALU*)
- A := R[ira0]; (*main data path*)
- B := R[irb];
- C0 := R[irc];
- C1 := q -> {v!16, imm} : C0 ;
- ira0 := Br -> 15'4 : ira;
- adr := stallL -> B[23:0] + {off.19!4, off} : {pcmux, 0'2};
- rd := Ldr & ~stallX & ~stall1;
- wr := Str & ~stallX & ~stall1;
- ben := p & ~q & v & ~stallX & ~stall1; (*byte enable*)
- sc0 := C1[1:0];
- sc1 := C1[3:2];
-
- (*right shifter*)
- s1 := (sc0 = 3) -> {(w -> B[2:0] : {B.31 ! 3}), B[31:3]} :
- (sc0 = 2) -> {(w -> B[1:0] : {B.31 ! 2}), B[31:2]} :
- (sc0 = 1) -> {(w -> B.0 : B.31), B[31:1]} : B;
- s2 := (sc1 = 3) -> {(w -> s1[11:0] : {B.31 ! 12}), s1[31:12]} :
- (sc1 = 2) -> {(w -> s1[7:0] : {B.31 ! 8}), s1[31:8]} :
- (sc1 = 1) -> {(w -> s1[3:0] : {B.31 ! 4}), s1[31:4]} : s1;
- s3 := C1.4 -> {(w -> s2[15:0] : {s2.31 ! 16}), s2[31:16]} : s2;
- (*left shifter*)
- t1 := (sc0 = 3) -> {B[28:0], 0'3} :
- (sc0 = 2) -> {B[29:0], 0'2} :
- (sc0 = 1) -> {B[30:0], 0'1} : B;
- t2 := (sc1 = 3) -> {t1[19:0], 0'12} :
- (sc1 = 2) -> {t1[23:0], 0'8} :
- (sc1 = 1) -> {t1[27:0], 0'4} : t1;
- t3 := C1.4 -> {t2[15:0], 0'16} : t2;
-
- aluRes :=
- ~op.3 ->
- (~op.2 ->
- (~op.1 ->
- (~op.0 -> (*Mov*)
- (q ->
- (~u -> {v!16 , imm} : {imm, 0'16}) :
- (~u -> C0 : (~v -> H : {N, Z, C, OV, 0'20, 58H'8}))) :
- t3 ): (*Lsl*)
- s3) : (*Asr, Ror*)
- (~op.1 ->
- (~op.0 -> B & C1 : B & ~C1) : (*And, Ann*)
- (~op.0 -> B | C1 : B ^ C1)) ): (*Ior, Xor*)
- (~op.2 ->
- (~op.1 ->
- (~op.0 -> B + C + (u&C) : B - C1 - (u&C)) : (*Add, Sub*)
- (~op.0 -> product[31:0] : quotient)) : (*Mul, Div*)
- (~op.1 ->
- fsum : (*Fad, Fsb*)
- (~op.0 -> fprod : fquot))) ; (*Fml, Fdv*)
- regwr := ~p & ~stall | (Ldr & ~stallX & ~stall1) | (Br & cond & v & ~stallX);
- a0 := ~adr.1 & ~adr.0;
- a1 := ~adr.1 & adr.0;
- a2 := adr.1 & ~adr.0;
- a3 := adr.1 & adr.0;
- inbusL := (~ben | a0) -> inbus[7:0] : a1 -> inbus[15:8] : a2 -> inbus[23:16] : inbus[31:24];
- inbusH := ~ben -> inbus[31:8] : 0'24;
- regmux := Ldr -> {inbusH, inbusL} : (Br & v) -> {0'8, nxpc, 0'2} : aluRes ;
- outbusB0 := A[7:0];
- outbusB1 := ben & a1 -> A[7:0] : A[15:8];
- outbusB2 := ben & a2 -> A[7:0] : A[23:16];
- outbusB3 := ben & a3 -> A[7:0] : A[31:24];
- outbus := {outbusB3, outbusB2, outbusB1, outbusB0};
- (*control unit*)
- S := N ^ OV;
- nxpc := PC + 1;
- cond := ins.27 ^ (
- (cc = 0) & N | (*MI, PL*)
- (cc = 1) & Z | (*EQ, NE*)
- (cc = 2) & C | (*CS, CC*)
- (cc = 3) & OV | (*VS, VC*)
- (cc = 4) & (C|Z) | (*LS, HI*)
- (cc = 5) & S | (*LT, GE*)
- (cc = 6) & (S|Z) | (*LE, GT*)
- (cc = 7));
- pcmux := ~rst -> 3FF800H'22 :
- stall -> PC :
- (Br & cond & u) -> offL[21:0] + nxpc :
- (Br & cond & ~u) -> C0[23:2] : nxpc;
- sa := aluRes.31;
- sb := B.31;
- sc := C1.31;
- stall := stallL | stallM | stallD | stallFA | stallFM | stallFD | stallX;
- stallL := (Ldr | Str) & ~stall1;
-
- (*assignments to registers*)
- PC := pcmux;
- PMsel := ~rst | (pcmux[21:12] = 03FFH'10);
- IR := stall -> IR : codebus;
- stall1 := stallX -> stall1 : stallL;
- R[ira0] := regwr -> regmux : A;
- N := regwr -> regmux.31 : N;
- Z := regwr -> (regmux = 0) : Z;
- C := Add -> (sb&sc) | (~sa&~sb&sc) | (~sa&sb&~sc&sa) :
- Sub -> (~sb&sc) | (sa&~sb&~sc) | (sa&sb&sc) : C;
- OV := Add -> (sa&~sb&~sc) | (~sa&sb&sc) :
- Sub -> (sa&~sb&sc) | (~sa&sb&~sc) : OV;
- H := Mul -> product[63:32] : Div -> remainder : H
- END RISC5.
|