`timescale 1ns / 1 ps module RISC5( // translated from Lola input clk, rst, stallX, input [31:0] inbus, codebus, output [23:0] adr, output rd, wr, ben, output [31:0] outbus); reg [21:0] PC; reg [31:0] IR; reg N, Z, C, OV, stall1, PMsel; reg [31:0] R[15:0]; reg [31:0] H; wire [21:0] pcmux, nxpc; wire cond, S, sa, sb, sc; wire [31:0] ins, pmout; wire p, q, u, v, w; wire [3:0] op, ira, ira0, irb, irc; wire [2:0] cc; wire [15:0] imm; wire [19:0] off; wire [23:0] offL; wire regwr, stall, stallL, stallM, stallD, stallFA, stallFM, stallFD; wire [1:0] sc1, sc0; wire a0, a1, a2, a3; wire [7:0] inbusL, outbusB0, outbusB1, outbusB2, outbusB3; wire [23:0] inbusH; wire [31:0] A, B, C0, C1, aluRes, regmux, s1, s2, s3, t1, t2, t3, quotient, remainder; wire [63:0] product; wire [31:0] fsum, fprod, fquot; wire Add, Sub, Mul, Div, Fadd, Fsub, Fmul, Fdiv, Ldr, Str, Br; assign adr = stallL ? (B[23:0] + {4'h0, off}) : {pcmux, 2'h0}; assign rd = ((Ldr & ~stallX) & ~stall1); assign wr = ((Str & ~stallX) & ~stall1); assign ben = ((((p & ~q) & v) & ~stallX) & ~stall1); assign outbus = {outbusB3, outbusB2, outbusB1, outbusB0}; PROM PM(.clk(clk), .adr(pcmux[8:0]), .data(pmout)); Multiplier mulUnit(.clk(clk), .run(Mul), .u(~u), .stall(stallM), .x(B), .y(C1), .z(product)); Divider divUnit(.clk(clk), .run(Div), .u(~u), .stall(stallD), .x(B), .y(C1), .quot(quotient), .rem(remainder)); FPAdder faddUnit(.clk(clk), .run((Fadd | Fsub)), .u(u), .v(v), .stall(stallFA), .x(B), .y({(Fsub ^ C0[31]), C0[30:0]}), .z(fsum)); FPMultiplier fmulUnit(.clk(clk), .run(Fmul), .stall(stallFM), .x(B), .y(C0), .z(fprod)); FPDivider fdivUnit(.clk(clk), .run(Fdiv), .stall(stallFD), .x(B), .y(C0), .z(fquot)); assign pcmux = ~rst ? 22'h3FF800 : stall ? PC : ((Br & cond) & u) ? (offL[21:0] + nxpc) : ((Br & cond) & ~u) ? C0[23:2] : nxpc; assign nxpc = (PC + 1); assign cond = (ins[27] ^ (((((((((cc == 0) & N) | ((cc == 1) & Z)) | ((cc == 2) & C)) | ((cc == 3) & OV)) | ((cc == 4) & (C | Z))) | ((cc == 5) & S)) | ((cc == 6) & (S | Z))) | (cc == 7))); assign S = (N ^ OV); assign sa = aluRes[31]; assign sb = B[31]; assign sc = C1[31]; assign ins = PMsel ? pmout : IR; assign p = ins[31]; assign q = ins[30]; assign u = ins[29]; assign v = ins[28]; assign w = ins[16]; assign op = ins[19:16]; assign ira = ins[27:24]; assign ira0 = Br ? 4'hF : ira; assign irb = ins[23:20]; assign irc = ins[3:0]; assign cc = ins[26:24]; assign imm = ins[15:0]; assign off = ins[19:0]; assign offL = ins[23:0]; assign regwr = (((~p & ~stall) | ((Ldr & ~stallX) & ~stall1)) | (((Br & cond) & v) & ~stallX)); assign stall = ((((((stallL | stallM) | stallD) | stallFA) | stallFM) | stallFD) | stallX); assign stallL = ((Ldr | Str) & ~stall1); assign sc1 = C1[3:2]; assign sc0 = C1[1:0]; assign a0 = (~adr[1] & ~adr[0]); assign a1 = (~adr[1] & adr[0]); assign a2 = (adr[1] & ~adr[0]); assign a3 = (adr[1] & adr[0]); assign inbusL = (~ben | a0) ? inbus[7:0] : a1 ? inbus[15:8] : a2 ? inbus[23:16] : inbus[31:24]; assign outbusB0 = A[7:0]; assign outbusB1 = (ben & a1) ? A[7:0] : A[15:8]; assign outbusB2 = (ben & a2) ? A[7:0] : A[23:16]; assign outbusB3 = (ben & a3) ? A[7:0] : A[31:24]; assign inbusH = ~ben ? inbus[31:8] : 24'h0; assign A = R[ira0]; assign B = R[irb]; assign C0 = R[irc]; assign C1 = q ? {{16{v}}, imm} : C0; assign aluRes = ~op[3] ? ~op[2] ? ~op[1] ? ~op[0] ? q ? ~u ? {{16{v}}, imm} : {imm, 16'h0} : ~u ? C0 : ~v ? H : {N, Z, C, OV, 20'h0, 8'h58} : t3 : s3 : ~op[1] ? ~op[0] ? (B & C1) : (B & ~C1) : ~op[0] ? (B | C1) : (B ^ C1) : ~op[2] ? ~op[1] ? ~op[0] ? ((B + C) + (u & C)) : ((B - C1) - (u & C)) : ~op[0] ? product[31:0] : quotient : ~op[1] ? fsum : ~op[0] ? fprod : fquot; assign regmux = Ldr ? {inbusH, inbusL} : (Br & v) ? {8'h0, nxpc, 2'h0} : aluRes; assign s1 = (sc0 == 3) ? {w ? B[2:0] : {3{B[31]}}, B[31:3]} : (sc0 == 2) ? {w ? B[1:0] : {2{B[31]}}, B[31:2]} : (sc0 == 1) ? {w ? B[0] : B[31], B[31:1]} : B; assign s2 = (sc1 == 3) ? {w ? s1[11:0] : {12{B[31]}}, s1[31:12]} : (sc1 == 2) ? {w ? s1[7:0] : {8{B[31]}}, s1[31:8]} : (sc1 == 1) ? {w ? s1[3:0] : {4{B[31]}}, s1[31:4]} : s1; assign s3 = C1[4] ? {w ? s2[15:0] : {16{s2[31]}}, s2[31:16]} : s2; assign t1 = (sc0 == 3) ? {B[28:0], 3'h0} : (sc0 == 2) ? {B[29:0], 2'h0} : (sc0 == 1) ? {B[30:0], 1'h0} : B; assign t2 = (sc1 == 3) ? {t1[19:0], 12'h0} : (sc1 == 2) ? {t1[23:0], 8'h0} : (sc1 == 1) ? {t1[27:0], 4'h0} : t1; assign t3 = C1[4] ? {t2[15:0], 16'h0} : t2; assign Add = (~p & (op == 8)); assign Sub = (~p & (op == 9)); assign Mul = (~p & (op == 10)); assign Div = (~p & (op == 11)); assign Fadd = (~p & (op == 12)); assign Fsub = (~p & (op == 13)); assign Fmul = (~p & (op == 14)); assign Fdiv = (~p & (op == 15)); assign Ldr = ((p & ~q) & ~u); assign Str = ((p & ~q) & u); assign Br = (p & q); always @ (posedge clk) begin PC <= pcmux; IR <= stall ? IR : codebus; 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; stall1 <= stallX ? stall1 : stallL; PMsel <= (~rst | (pcmux[21:12] == 10'h3FF)); R[ira0] <= regwr ? regmux : A; H <= Mul ? product[63:32] : Div ? remainder : H; end endmodule