Project: mrisc1

Contents

Verilog Files

mrisc1.v
rom1.v
alu.v
iformat.v
MEM_stage.v
muxi.v
reg_file.v
rformat.v
IF_stage.v
ID_stage.v
EX_stage.v

Quartus Files

fit.summary
tan.summary

Verilog Files

mrisc1.v

module mrisc1(input clock, input reset, 
    output reg [7:0] pc, output [31:0] ir, 
    output we, output [4:0] rd, output [31:0] results,
    output [4:0] active
);

// instantiate memory
wire [7:0] next_pc;
assign next_pc = pc + 1'b1;

rom1 inst_cache(
    .address(next_pc),
    .clock(clock),
    .q(ir)
);

always @(posedge clock or negedge reset)
    if (!reset) 
        pc <= 8'hff; // so that next_pc starts at zero
    else 
        pc <= next_pc;

// Instantiate register file

wire [31:0] da, db, dc;
wire [4:0] ra, rb, rc;
wire write_enable;

assign {rb, ra} = ID_in[9:0]; 

reg_file regs(
    .clock(clock),
    .da(da),
    .db(db),
    .dc(dc),
    .ra(ra),
    .rb(rb),
    .rc(rc),
    .write_enable(write_enable)
    );

// fetch stage

wire [33:0] IF_out;
reg [31:0] immedse2, immedse3;
wire [31:0] immedse1, jump_target;
assign jump_target = {6'h0,ir[25:0]};
IF_stage stage1(ir,IF_out,immedse1);

// decode stage

reg [33:0] ID_in;
wire [31:0] ID_out;
ID_stage stage2(ID_in,ID_out);

// execute stage

reg [31:0] EX_in;
wire [24:0] EX_out;
wire [31:0] qd;

EX_stage stage3(EX_in,da,db,immedse3,EX_out,qd);

// memory stage

wire [31:0] qm = 0;
reg [24:0] MEM_in;
wire [5:0] MEM_out;

MEM_stage stage4(MEM_in,MEM_out,qd,qm,dc,write_enable);


//----------------------------------------------------------
// send the output of the ALU back to the register file

//assign dc = dalu;
assign rc = MEM_out[4:0];
assign we = write_enable;
assign rd = rc;
assign results = dc; // also send output outside the module for display
assign active = {1'b0, MEM_out[5], EX_out[24], ID_out[31], IF_out[33]};

always @(posedge clock)
begin
    ID_in <= IF_out;
    immedse3 <= immedse2;
    immedse2 <= immedse1;
    EX_in <= ID_out;
    MEM_in <= EX_out;
end

endmodule

rom1.v

// Quartus II Verilog Template
// Single Port ROM

module rom1
#(parameter DATA_WIDTH=32, parameter ADDR_WIDTH=8)
(
    input [(ADDR_WIDTH-1):0] address,
    input clock,  
    output reg [(DATA_WIDTH-1):0] q
);

    // Declare the ROM variable
    reg [DATA_WIDTH-1:0] rom[0:2**ADDR_WIDTH-1];

    // Initialize the ROM with $readmemb.  Put the memory contents
    // in the file single_port_rom_init.txt.  Without this file,
    // this design will not compile.
    // See Verilog LRM 1364-2001 Section 17.2.8 for details on the
    // format of this file.

    initial
    begin
        $readmemh("inst.txt", rom);
    end

    always @ (posedge clock)
    begin
        q <= rom[address];
    end

endmodule

alu.v

/*
*   control:
*    000  add, signed
*    001  subtract, signed
*    010  add, unsigned
*    011  subtract, unsigned
* --------------------------------------------
*    100  AND
*    101  OR
*    110  XOR
*    111  NOR
*/  
module alu(a,b,control,c,zero,neg,ovfl);
parameter BITS = 32;
input [BITS-1:0] a, b;
input [3:0] control;
output [BITS-1:0] c;
output zero, neg, ovfl;

wire subtract;
assign subtract = control[0];

// add-subtract unit
wire [BITS-1:0] sum;
wire [BITS-1:0] bn;
wire cin, cout;
assign cin = subtract;
assign bn = (subtract? ~b: b);
assign {cout, sum} = a+bn+cin;

// logic unit
reg [BITS-1:0] out;
always
    case (control[1:0])
    2'b00: out = a&b;
    2'b01: out = a|b;
    2'b10: out = a^b;
    2'b11: out = ~(a|b);
    endcase

wire zero, sgn, unsgn;
assign zero = ~(|sum);
assign sgn  = (sum[BITS-1]? (~a[BITS-1])&(~bn[BITS-1]): a[BITS-1]&bn[BITS-1] );
assign unsgn = cout^subtract;
assign ovfl = (control[1]? unsgn: sgn);
assign neg = (control[1]? unsgn: sum[BITS-1]);

assign c = control[3]? {31'h0,neg}: (control[2]? out: sum);

endmodule

iformat.v

module iformat(input [5:0] op,output [5:0] control, output reg [1:0] muxi);

// opcodes    
`include "opcodes.txt"

reg [3:0] acontrol;
reg [1:0] mem;
`define LW_C 1
`define SW_C 2

always
    case (op)
    ADDI: 
    begin
        acontrol <= 4'b0000; // add
        muxi <= 2'b01; // se 
    end
    ADDIU:
    begin
        acontrol <= 4'b0010; // addu
        muxi <= 2'b01; // se
    end
    ANDI: 
    begin
        acontrol <= 4'b0100; // andi
        muxi <= 2'b10;
    end
    ORI: 
    begin
        acontrol <= 4'b0101; // ori
        muxi <= 2'b10;
    end
    XORI: 
    begin 
        acontrol <= 4'b0110; // xor
        muxi <= 2'b10;
    end
    LUI: 
    begin
        acontrol <= 4'b0101; // or
        muxi <= 2'b11; // hi
    end
    SLTI:
    begin
        acontrol <= 4'b1001;
        muxi = 2'b01;
    end
    SLTIU:
    begin
        acontrol = 4'b1011;
        muxi = 2'b01;
    end
    LW:
    begin
        acontrol = 4'b0000;
        muxi = 2'b01;
    end
    SW:
    begin
        acontrol = 4'b0000;
        muxi = 2'b01;
    end
    default: 
    begin
        acontrol <= 4'b0000;
        muxi <= 2'b00; // nop
    end
    endcase

always
    case (op)
    LW: 
        mem <= `LW_C;
    SW:
        mem <= `SW_C;
    default:
        mem <= 2'b00;
    endcase
    
assign control = {mem,acontrol};    
    
endmodule

MEM_stage.v

module MEM_stage(
    input [24:0] MEM_in,
    output [5:0] MEM_out,
    input [31:0] qd, qm,
    output [31:0] qe,
    output write_enable
);
wire active;
wire [5:0] op;
wire [6:0] fn;
wire [4:0] rd,shf;
wire [5:0] control;
wire [1:0] muxc;

assign {active,op,fn,control,rd} = MEM_in;


assign qe = qd;
assign write_enable = active;


assign MEM_out = {active, rd};

endmodule

muxi.v

/*
*   control:
*    00  b
*    01  immedse, (immed sign-extended)
*    10  {16'h0000, immed} (not sign-extended)
*    11  {immed, 16'h0000}
*/
module muxi
#(parameter BITS = 32)
(
    output reg [BITS-1:0] dst, 
    input [BITS-1:0] b, immedse,
    input [1:0] control
);

always
    case (control)
    2'b00: dst = b;
    2'b01: dst = immedse;
    2'b10: dst = {16'h0000, immedse[15:0]};
    2'b11: dst = {immedse[15:0],16'h0000};
    endcase
endmodule

reg_file.v

module reg_file(clock,da,db,dc,ra,rb,rc,write_enable);
parameter BITS = 32;
input [BITS-1:0] dc;
output [BITS-1:0] da,db;
input [4:0] ra,rb,rc;
input clock, write_enable;
reg [BITS-1:0] r[0:31];

wire aflag = write_enable && (rc==ra) && ra;
wire bflag = write_enable && (rc==rb) && rb;

wire [BITS-1:0] qa,qb;

always @(posedge clock)
begin
    if (write_enable) r[rc] = dc;
end

assign    qa = ra? r[ra]: 0;
assign    qb = rb? r[rb]: 0;


// ensure read after write
assign da = aflag? dc: qa;
assign db = bflag? dc: qb;

endmodule            

rformat.v

module rformat(input [5:0] fn, output [5:0] control);

// opcodes    
`include "opcodes.txt"

reg [3:0] acontrol;

always
    case (fn)
    NOR: acontrol = 4'b0111;
    AND: acontrol = 4'b0100;
    OR: acontrol = 4'b0101;
    XOR: acontrol = 4'b0110;
    ADD: acontrol = 4'b0000;
    ADDU: acontrol = 4'b0010;
    SUB: acontrol = 4'b0001;
    SUBU: acontrol = 4'b0011;
    SLT:  acontrol = 4'b1001;
    SLTU: acontrol = 4'b1011;
    default: acontrol = 4'b0000;
    endcase
    
assign control = {2'b00,acontrol};
    
endmodule

IF_stage.v

module IF_stage(input [31:0] ir, 
    output [33:0] IF_out, output [31:0] immedse);

wire [5:0] op;
reg [6:0] fn;
reg [4:0] ra,rb,rd;

// COMMON FIELDS
`define RT 20:16
`define RS 25:21
`define OP 31:26
// RFORMAT FIELDS
`define FN 5:0
`define SH 10:6
`define RD 15:11
// IFORMAT
`define IMM 15:0
wire [4:0] shf = ir[`SH];

assign op = ir[`OP];
assign immedse = {(ir[15]?16'hffff:16'h0000),ir[`IMM]};

always
begin
    ra <= ir[`RS];
    if (op>1)
    begin
        rd <= ir[`RT];
        fn <= {1'b0,ir[`FN]};
        rb <= 5'h0;
    end
    else if (op==6'b1)
    begin
        fn <= {1'b1,ir[`FN]};
        rd <= 5'd0;
        rb <= 5'd0;
    end
    else
    begin
        fn <= {1'b0,ir[`FN]};
        rd <= ir[`RD];
        rb <= ir[`RT];
    end
end

wire active = ir != 0;
assign IF_out = {active,shf,fn,op,rd,rb,ra};

endmodule

ID_stage.v

module ID_stage(input [33:0] ID_in, output [31:0] ID_out);

wire active;
wire [5:0] op;
wire [6:0] fn;
wire [4:0] ra,rb,rd,shf;

assign {active,shf,fn,op,rd,rb,ra} = ID_in;

// instantiate r-format control unit
wire [5:0] rcontrol;
rformat unit1(
    .fn(fn),
    .control(rcontrol)
);
    
// instantiate i-format control unit
wire [5:0] icontrol;
wire [1:0] muxi;
iformat unit2(
    .op(op),
    .control(icontrol),
    .muxi(muxi)
    );

wire flag = (op==0);
wire [5:0] control = (flag? rcontrol: icontrol);
wire [1:0] muxc = (flag? 2'b00: muxi);
assign ID_out = {active,op,fn,shf,control,muxc,rd};

endmodule

EX_stage.v

module EX_stage(
    input [33:0] EX_in,
    input [31:0] qa, qb, immedse, 
    output [24:0] EX_out, 
    output [31:0] qd
);
wire active;
wire [5:0] op;
wire [6:0] fn;
wire [4:0] rd,shf;
wire [5:0] control;
wire [1:0] muxc;

assign {active,shf,op,fn,control,muxc,rd} = EX_in;

wire [31:0] dmuxi; // muxi output
muxi mux1(
    .dst(dmuxi),
    .b(qb),
    .immedse(immedse),
    .control(muxc)
    );
    
wire [31:0] dalu; // alu output

wire zero, ovfl;

alu my_alu(
    .a(qa),
    .b(dmuxi),
    .control(control[3:0]),
    .c(dalu)
    );
    
assign qd = dalu;
assign EX_out = {active, op, fn, control, rd};

endmodule

Quartus Compilation Summary

fit.summary

Fitter Status : Successful - Tue Apr 24 17:06:57 2012
Quartus II Version : 9.0 Build 235 06/17/2009 SP 2 SJ Web Edition
Revision Name : mrisc1
Top-level Entity Name : mrisc1
Family : Cyclone II
Device : EP2C35F672C6
Timing Models : Final
Total logic elements : 399 / 33,216 ( 1 % )
    Total combinational functions : 377 / 33,216 ( 1 % )
    Dedicated logic registers : 118 / 33,216 ( < 1 % )
Total registers : 118
Total pins : 85 / 475 ( 18 % )
Total virtual pins : 0
Total memory bits : 10,240 / 483,840 ( 2 % )
Embedded Multiplier 9-bit elements : 0 / 70 ( 0 % )
Total PLLs : 0 / 4 ( 0 % )

tan.summary

--------------------------------------------------------------------------------------
Timing Analyzer Summary
--------------------------------------------------------------------------------------

Type           : Worst-case tco
Slack          : N/A
Required Time  : None
Actual Time    : 29.037 ns
From           : reg_file:regs|altsyncram:r_rtl_1|altsyncram_99e1:auto_generated|ram_block1a0~portb_address_reg4
To             : results[1]
From Clock     : clock
To Clock       : --
Failed Paths   : 0

Type           : Clock Setup: 'clock'
Slack          : N/A
Required Time  : None
Actual Time    : 43.58 MHz ( period = 22.947 ns )
From           : reg_file:regs|r_1_bypass[4]
To             : reg_file:regs|altsyncram:r_rtl_1|altsyncram_99e1:auto_generated|ram_block1a0~porta_datain_reg18
From Clock     : clock
To Clock       : clock
Failed Paths   : 0

Type           : Total number of failed paths
Slack          : 
Required Time  : 
Actual Time    : 
From           : 
To             : 
From Clock     : 
To Clock       : 
Failed Paths   : 0

--------------------------------------------------------------------------------------


Maintained by John Loomis, last updated Fri May 18 11:38:36 2012