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