OpenCores
URL https://opencores.org/ocsvn/mips_16/mips_16/trunk

Subversion Repositories mips_16

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /mips_16/trunk
    from Rev 3 to Rev 4
    Reverse comparison

Rev 3 → Rev 4

/rtl/WB_stage.v
0,0 → 1,45
/***************************************************
* Module: WB_stage
* Project: mips_16
* Author: fzy
* Description:
* Write back stage
*
* Revise history:
*
***************************************************/
`timescale 1ns/1ps
`include "mips_16_defs.v"
module WB_stage
(
//input clk,
// from EX stage
input [36:0] pipeline_reg_in, // [36:21],16bits: ex_alu_result[15:0]
// [20:5],16bits: mem_read_data[15:0]
// [4:0],5bits: write_back_en, write_back_dest[2:0], write_back_result_mux,
// to register file
output reg_write_en,
output [2:0] reg_write_dest,
output [15:0] reg_write_data,
output [2:0] wb_op_dest
);
wire [15:0] ex_alu_result = pipeline_reg_in[36:21];
wire [15:0] mem_read_data = pipeline_reg_in[20:5];
wire write_back_en = pipeline_reg_in[4];
wire [2:0] write_back_dest = pipeline_reg_in[3:1];
wire write_back_result_mux = pipeline_reg_in[0];
/********************** to register file *********************/
assign reg_write_en = write_back_en;
assign reg_write_dest = write_back_dest;
assign reg_write_data = (write_back_result_mux)? mem_read_data : ex_alu_result;
/********************** to hazard detection unit *********************/
assign wb_op_dest = pipeline_reg_in[3:1];
endmodule
/rtl/EX_stage.v
0,0 → 1,59
/***************************************************
* Module: EX_stage
* Project: mips_16
* Author: fzy
* Description:
* alu
*
* Revise history:
*
***************************************************/
`timescale 1ns/1ps
`include "mips_16_defs.v"
module EX_stage
(
input clk,
input rst,
// from ID_stage
input [56:0] pipeline_reg_in, // [56:22],35bits: ex_alu_cmd[2:0], ex_alu_src1[15:0], ex_alu_src2[15:0]
// [21:5],17bits: mem_write_en, mem_write_data[15:0]
// [4:0],5bits: write_back_en, write_back_dest[2:0], write_back_result_mux,
// to MEM_stage
output reg [37:0] pipeline_reg_out, // [37:22],16bits: ex_alu_result[15:0];
// [21:5],17bits: mem_write_en, mem_write_data[15:0]
// [4:0],5bits: write_back_en, write_back_dest[2:0], write_back_result_mux,
// to hazard detection unit
output [2:0] ex_op_dest
);
wire [2:0] alu_cmd = pipeline_reg_in[56:54]; //S2
wire [15:0] alu_src1 = pipeline_reg_in[53:38];
wire [15:0] alu_src2 = pipeline_reg_in[37:22];
wire [15:0] ex_alu_result;
/********************** ALU *********************/
alu alu_inst(
.a ( alu_src1),
.b ( alu_src2),
.cmd ( alu_cmd),
.r ( ex_alu_result)
);
/********************** singals to MEM_stage *********************/
always @ (posedge clk) begin
if(rst) begin
pipeline_reg_out[37:0] <= 0;
end
else begin
pipeline_reg_out[37:22] <= ex_alu_result;
pipeline_reg_out[21:0] <= pipeline_reg_in[21:0];
end
end
/********************** to hazard detection unit *********************/
assign ex_op_dest = pipeline_reg_in[3:1];
endmodule
/rtl/ID_stage.v
0,0 → 1,291
/***************************************************
* Module: ID_stage
* Project: mips_16
* Author: fzy
* Description:
* IR, and instruction decoding
*
* Revise history:
*
***************************************************/
`timescale 1ns/1ps
`include "mips_16_defs.v"
 
module ID_stage
(
input clk,
input rst,
input instruction_decode_en,
//input insert_bubble,
// to EX_stage
output reg [56:0] pipeline_reg_out, // [56:22],35bits: ex_alu_cmd[2:0], ex_alu_src1[15:0], ex_alu_src2[15:0]
// [21:5],17bits: mem_write_en, mem_write_data[15:0]
// [4:0],5bits: write_back_en, write_back_dest[2:0], write_back_result_mux,
// to IF_stage
input [15:0] instruction,
output [5:0] branch_offset_imm,
output reg branch_taken,
// to register file
output [2:0] reg_read_addr_1, // register file read port 1 address
output [2:0] reg_read_addr_2, // register file read port 2 address
input [15:0] reg_read_data_1, // register file read port 1 data
input [15:0] reg_read_data_2, // register file read port 2 data
// to hazard detection unit
output [2:0] decoding_op_src1, //source_1 register number
output [2:0] decoding_op_src2 //source_2 register number
);
/********************** internal wires ***********************************/
//----------------- Instruction Register signals --------------------//
reg [15:0] instruction_reg;
wire [3:0] ir_op_code; //operation code
wire [2:0] ir_dest; //destination register number
wire [2:0] ir_src1; //source_1 register number
wire [2:0] ir_src2; //source_2 register number
wire [5:0] ir_imm; //immediate number carried by the instruction
//---------------- data path control signals --------------------------//
// write back stage signals
reg write_back_en; // S3
wire [2:0] write_back_dest; // dest
reg write_back_result_mux; // S1
// mem stage signals
wire mem_write_en;
wire [15:0] mem_write_data;
// ex stage signals
reg [2:0] ex_alu_cmd; //S2
wire [15:0] ex_alu_src1;
wire [15:0] ex_alu_src2;
// instruction decode stage signals
reg alu_src2_mux; // S4
wire decoding_op_is_branch; //S5
wire decoding_op_is_store; //S6
wire [3:0] ir_op_code_with_bubble;
wire [2:0] ir_dest_with_bubble;
//reg branch_condition_satisfied;
/********************** Instruction Register *********************/
always @ (posedge clk or posedge rst) begin
if(rst) begin
instruction_reg <= 0;
end
else begin
if(instruction_decode_en) begin
instruction_reg <= instruction;
end
end
end
assign ir_op_code = instruction_reg[15:12];
assign ir_dest = instruction_reg[11: 9];
assign ir_src1 = instruction_reg[ 8: 6];
assign ir_src2 = (decoding_op_is_store)? instruction_reg[11: 9] : instruction_reg[ 5: 3];
assign ir_imm = instruction_reg[ 5: 0];
/********************** pipeline bubble insertion *********************/
// if instrcution decode is frozen, insert bubble operations into the pipeline
assign ir_op_code_with_bubble = ( instruction_decode_en )? ir_op_code : 0;
// if instrcution decode is frozen, force destination reg number to 0,
// this operation is to prevent pipeline stall.
assign ir_dest_with_bubble = ( instruction_decode_en )? ir_dest : 0;
/********************** Data path control logic *********************/
always @ (*) begin
if(rst) begin
write_back_en = 0; // S3
write_back_result_mux = 0; // S1
ex_alu_cmd = 0; // S2
alu_src2_mux = 0; // S4
end
else begin
case( ir_op_code_with_bubble )
`OP_NOP :
begin
write_back_en = 0; // S3
write_back_result_mux = 1'bx; // S1
ex_alu_cmd = `ALU_NC; // S2
alu_src2_mux = 1'bx; // S4
end
`OP_ADD :
begin
write_back_en = 1; // S3
write_back_result_mux = 0; // S1
ex_alu_cmd = `ALU_ADD; // S2
alu_src2_mux = 0; // S4
end
`OP_SUB :
begin
write_back_en = 1; // S3
write_back_result_mux = 0; // S1
ex_alu_cmd = `ALU_SUB; // S2
alu_src2_mux = 0; // S4
end
`OP_AND :
begin
write_back_en = 1; // S3
write_back_result_mux = 0; // S1
ex_alu_cmd = `ALU_AND; // S2
alu_src2_mux = 0; // S4
end
`OP_OR :
begin
write_back_en = 1; // S3
write_back_result_mux = 0; // S1
ex_alu_cmd = `ALU_OR; // S2
alu_src2_mux = 0; // S4
end
`OP_XOR :
begin
write_back_en = 1; // S3
write_back_result_mux = 0; // S1
ex_alu_cmd = `ALU_XOR; // S2
alu_src2_mux = 1'bx; // S4
end
`OP_SL :
begin
write_back_en = 1; // S3
write_back_result_mux = 0; // S1
ex_alu_cmd = `ALU_SL; // S2
alu_src2_mux = 0; // S4
end
`OP_SR :
begin
write_back_en = 1; // S3
write_back_result_mux = 0; // S1
ex_alu_cmd = `ALU_SR; // S2
alu_src2_mux = 0; // S4
end
`OP_SRU :
begin
write_back_en = 1; // S3
write_back_result_mux = 0; // S1
ex_alu_cmd = `ALU_SRU; // S2
alu_src2_mux = 0; // S4
end
`OP_ADDI:
begin
write_back_en = 1; // S3
write_back_result_mux = 0; // S1
ex_alu_cmd = `ALU_ADD; // S2
alu_src2_mux = 1; // S4
end
`OP_LD :
begin
write_back_en = 1; // S3
write_back_result_mux = 1; // S1
ex_alu_cmd = `ALU_ADD; // S2
alu_src2_mux = 1; // S4
end
`OP_ST :
begin
write_back_en = 0; // S3
write_back_result_mux = 1'bx; // S1
ex_alu_cmd = `ALU_ADD; // S2
alu_src2_mux = 1; // S4
end
`OP_BZ :
begin
write_back_en = 0; // S3
write_back_result_mux = 1'bx; // S1
ex_alu_cmd = `ALU_NC; // S2
alu_src2_mux = 1; // S4
end
default :
begin
write_back_en = 0; // S3
write_back_result_mux = 1'bx; // S1
ex_alu_cmd = `ALU_NC; // S2
alu_src2_mux = 1'bx; // S4
`ifndef CODE_FOR_SYNTHESIS
$display("ERROR: Unknown Instruction: %b", ir_op_code_with_bubble);
//$stop;
`endif
end
endcase
end
end
assign decoding_op_is_branch = ( ir_op_code == `OP_BZ )? 1 : 0; // S5
assign decoding_op_is_store = ( ir_op_code == `OP_ST )? 1 : 0; // S6
/********************** singals to EX_stage *********************/
assign mem_write_data = reg_read_data_2;
assign mem_write_en = decoding_op_is_store;
assign write_back_dest = ir_dest_with_bubble;
assign ex_alu_src1 = reg_read_data_1;
assign ex_alu_src2 = (alu_src2_mux)? {{10{ir_imm[5]}},ir_imm} : reg_read_data_2;
// pipeline_reg_out:
// [56:22],35bits: ex_alu_cmd[2:0], ex_alu_src1[15:0], ex_alu_src2[15:0],
// [21:5],17bits: mem_write_en, mem_write_data[15:0],
// [4:0],5bits: write_back_en, write_back_dest[2:0], write_back_result_mux,
always @ (posedge clk or posedge rst) begin
if(rst) begin
pipeline_reg_out[56:0] <= 0;
end
else begin
pipeline_reg_out[56:0] <= {
ex_alu_cmd[2:0], // pipeline_reg_out[56:54] //S2
ex_alu_src1[15:0], // pipeline_reg_out[53:38]
ex_alu_src2[15:0], // pipeline_reg_out[37:22]
mem_write_en, // pipeline_reg_out[21] //
mem_write_data[15:0], // pipeline_reg_out[20:5] //
write_back_en, // pipeline_reg_out[4] //S3
write_back_dest[2:0], // pipeline_reg_out[3:1] //dest
write_back_result_mux // pipeline_reg_out[0] //S1
};
end
end
/********************** interface with register file *********************/
assign reg_read_addr_1 = ir_src1;
assign reg_read_addr_2 = ir_src2;
/********************** branch signals generate *********************/
always @ (*) begin
if(decoding_op_is_branch) begin
case( ir_dest_with_bubble )
`BRANCH_Z :
begin
if(reg_read_data_1 == 0)
branch_taken = 1;
else
branch_taken = 0;
end
default:
begin
branch_taken = 0;
`ifndef CODE_FOR_SYNTHESIS
$display("ERROR: Unknown branch condition %b, in branch instruction %b \n", ir_dest_with_bubble, ir_op_code_with_bubble);
//$stop;
`endif
end
endcase
end
else begin
branch_taken = 0;
end
end
assign branch_offset_imm = ir_imm;
//assign branch_taken = decoding_op_is_branch & branch_condition_satisfied ;
/********************** to hazard detection unit *********************/
assign decoding_op_src1 = ir_src1;
assign decoding_op_src2 = (
ir_op_code == `OP_NOP ||
ir_op_code == `OP_ADDI ||
ir_op_code == `OP_LD ||
ir_op_code == `OP_BZ
)?
3'b000 : ir_src2;
endmodule
/rtl/instruction_mem.v
0,0 → 1,81
/***************************************************
* Module: instruction_mem
* Project: mips_16
* Author: fzy
* Description:
* a rom
*
* Revise history:
*
***************************************************/
`timescale 1ns/1ps
`include "mips_16_defs.v"
`ifdef USE_SIMULATION_CODE
module instruction_mem // a rtl simulation rom, rom initial code can be found in the testbench
(
input clk, // asynchronized!!
input [`PC_WIDTH-1:0] pc,
output [15:0] instruction
);
reg [15:0] rom [2**`INSTR_MEM_ADDR_WIDTH-1 : 0];
wire [`INSTR_MEM_ADDR_WIDTH-1 : 0] rom_addr = pc[`INSTR_MEM_ADDR_WIDTH-1 : 0];
// always @ (posedge clk) begin
// always @ (*) begin
// instruction = rom[rom_addr];
// end
assign instruction = rom[rom_addr];
endmodule
`endif
 
`ifndef USE_SIMULATION_CODE
module instruction_mem // a synthesisable rom implementation
(
input clk, // asynchronized!!
input [`PC_WIDTH-1:0] pc,
output reg [15:0] instruction
);
wire [`INSTR_MEM_ADDR_WIDTH-1 : 0] rom_addr = pc[`INSTR_MEM_ADDR_WIDTH-1 : 0];
// ASM code in rom:
// L1: ADDI R1,R0,8
// ADDI R2,R1,8
// ADDI R3,R2,8
// ADD R4,R2,R3
// ST R4,R1,2
// LD R5,R1,2
// SUB R6,R4,R5
// BZ R6,L1
// ADDI R7,R7,1
always @(*)
case (rom_addr)
4'b0000: instruction = 16'b1001001000001000;
4'b0001: instruction = 16'b1001010001001000;
4'b0010: instruction = 16'b1001011010001000;
4'b0011: instruction = 16'b0001100010011000;
4'b0100: instruction = 16'b1011100001000010;
4'b0101: instruction = 16'b1010101001000010;
4'b0110: instruction = 16'b0010110100101000;
4'b0111: instruction = 16'b1100000110111000;
4'b1000: instruction = 16'b1001111111000001;
4'b1001: instruction = 16'b0000000000000000;
4'b1010: instruction = 16'b0000000000000000;
4'b1011: instruction = 16'b0000000000000000;
4'b1100: instruction = 16'b0000000000000000;
4'b1101: instruction = 16'b0000000000000000;
4'b1110: instruction = 16'b0000000000000000;
4'b1111: instruction = 16'b0000000000000000;
default: instruction = 16'b0000000000000000;
endcase
endmodule
`endif
/rtl/mips_16_defs.v
0,0 → 1,55
/***************************************************
* Module:
* Project: mips_16
* Author:
* Description:
*
*
* Revise history:
*
***************************************************/
`ifndef _MIPS_16_DEFS
`define _MIPS_16_DEFS
//`define CODE_FOR_SYNTHESIS // uncomment this macro will remove all non-systhesis code
`define USE_SIMULATION_CODE // uncomment this to use simulation instruction memory
`define PC_WIDTH 8
`define INSTR_MEM_ADDR_WIDTH 8
`define DATA_MEM_ADDR_WIDTH 8
/************** Operation Code in instructions ****************/
`define OP_NOP 4'b0000
`define OP_ADD 4'b0001
`define OP_SUB 4'b0010
`define OP_AND 4'b0011
`define OP_OR 4'b0100
`define OP_XOR 4'b0101
`define OP_SL 4'b0110
`define OP_SR 4'b0111
`define OP_SRU 4'b1000
`define OP_ADDI 4'b1001
`define OP_LD 4'b1010
`define OP_ST 4'b1011
`define OP_BZ 4'b1100
/************** ALU operation command ****************/
`define ALU_NC 3'bxxx // not care
`define ALU_ADD 3'b000
`define ALU_SUB 3'b001
`define ALU_AND 3'b010
`define ALU_OR 3'b011
`define ALU_XOR 3'b100
`define ALU_SL 3'b101
`define ALU_SR 3'b110
`define ALU_SRU 3'b111
/************** Branch condition code ****************/
`define BRANCH_Z 3'b000
//`define BRANCH_GT 3'b001
//`define BRANCH_LE 3'b010
`endif
/rtl/IF_stage.v
0,0 → 1,56
/***************************************************
* Module: IF_stage
* Project: mips_16
* Author: fzy
* Description:
* PC, IMEM,
*
* Revise history:
*
***************************************************/
`timescale 1ns/1ps
`include "mips_16_defs.v"
 
 
module IF_stage
(
input clk,
input rst, //active high
input instruction_fetch_en,
input [5:0] branch_offset_imm,
input branch_taken,
output reg [`PC_WIDTH-1:0] pc,
output [15:0] instruction
);
// pc control
always @ (posedge clk or posedge rst) begin
if (rst) begin
pc <= `PC_WIDTH'b0;
end
else begin
if(instruction_fetch_en) begin
if(branch_taken)
//don't forget sign bit expansion
pc <= pc + {{(`PC_WIDTH-6){branch_offset_imm[5]}}, branch_offset_imm[5:0]};
else
pc <= pc + `PC_WIDTH'd1;
end
end
end
// instruction memory, or rom
instruction_mem imem(
.clk (clk),
.pc (pc),
.instruction (instruction)
);
endmodule
 
 
 
/rtl/MEM_stage.v
0,0 → 1,63
/***************************************************
* Module: MEM_stage
* Project: mips_16
* Author: fzy
* Description:
* a ram
*
* Revise history:
*
***************************************************/
`timescale 1ns/1ps
`include "mips_16_defs.v"
 
module MEM_stage
(
input clk,
input rst,
// from EX_stage
input [37:0] pipeline_reg_in, // [37:22],16bits: ex_alu_result[15:0];
// [21:5],17bits: mem_write_en, mem_write_data[15:0]
// [4:0],5bits: write_back_en, write_back_dest[2:0], write_back_result_mux,
// to WB_stage
output reg [36:0] pipeline_reg_out, // [36:21],16bits: ex_alu_result[15:0]
// [20:5],16bits: mem_read_data[15:0]
// [4:0],5bits: write_back_en, write_back_dest[2:0], write_back_result_mux,
output [2:0] mem_op_dest
);
wire [15:0] ex_alu_result = pipeline_reg_in[37:22];
wire mem_write_en = pipeline_reg_in[21];
wire [15:0] mem_write_data = pipeline_reg_in[20:5];
wire [15:0] mem_read_data ;
/********************** Data memory *********************/
// a ram
data_mem dmem (
.clk(clk),
.mem_access_addr ( ex_alu_result ),
.mem_write_data ( mem_write_data ),
.mem_write_en ( mem_write_en ),
.mem_read_data ( mem_read_data )
);
/********************** singals to WB_stage *********************/
always @ (posedge clk) begin
if(rst) begin
pipeline_reg_out[36:0] <= 0;
end
else begin
pipeline_reg_out[36:21] <= ex_alu_result;
pipeline_reg_out[20:5] <= mem_read_data ;
pipeline_reg_out[4:0] <= pipeline_reg_in[4:0];
end
end
/********************** to hazard detection unit *********************/
assign mem_op_dest = pipeline_reg_in[3:1];
 
endmodule
/rtl/alu.v
0,0 → 1,52
/***************************************************
* Module: alu
* Project: mips_16
* Author: fzy
* Description:
* alu implementation
*
* Revise history:
*
***************************************************/
`timescale 1ns/1ps
`include "mips_16_defs.v"
module alu
(
input [15:0] a, //src1
input [15:0] b, //src2
input [2:0] cmd, //function sel
output reg [15:0] r //result
);
always @ (*) begin
case(cmd)
`ALU_NC :
r = 16'bx;
`ALU_ADD:
r = a + b;
`ALU_SUB:
r = a - b;
`ALU_AND:
r = a & b;
`ALU_OR :
r = a | b;
`ALU_XOR:
r = a ^ b;
`ALU_SL :
r = a << b;
`ALU_SR :
r = {{16{a[15]}},a} >> b;
`ALU_SRU :
r = {16'b0,a} >> b;
default :
begin
r = 0;
`ifndef CODE_FOR_SYNTHESIS
$display("ERROR: Unknown alu cmd: %b \n", cmd);
//$stop;
`endif
end
endcase
end
endmodule
/rtl/register_file.v
0,0 → 1,82
/***************************************************
* Module: register_file
* Project: mips_16
* Author: fzy
* Description:
* a 8-entry 16-bit register file,
* with 1 synchronized write port and 2 asynchonized read port
*
* NOTE: for Register 0, read data from it will always be 0,
* and write operatioins will also be discarded.
*
* Revise history:
*
***************************************************/
`timescale 1ns/1ps
`include "mips_16_defs.v"
 
module register_file
(
input clk,
input rst,
// write port
input reg_write_en,
input [2:0] reg_write_dest,
input [15:0] reg_write_data,
//read port 1
input [2:0] reg_read_addr_1,
output [15:0] reg_read_data_1,
//read port 2
input [2:0] reg_read_addr_2,
output [15:0] reg_read_data_2
);
reg [15:0] reg_array [7:0];
// write port
//reg [2:0] i;
always @ (posedge clk or posedge rst) begin
if(rst) begin
// for(i=0; i<8; i=i+1)
// reg_array[i] <= 15'b0;
reg_array[0] <= 15'b0;
reg_array[1] <= 15'b0;
reg_array[2] <= 15'b0;
reg_array[3] <= 15'b0;
reg_array[4] <= 15'b0;
reg_array[5] <= 15'b0;
reg_array[6] <= 15'b0;
reg_array[7] <= 15'b0;
end
else begin
if(reg_write_en) begin
reg_array[reg_write_dest] <= reg_write_data;
end
end
end
//read port 1
// always @ (*) begin
// if( reg_read_addr_1 == 0) begin
// reg_read_data_1 = 15'b0;
// end
// else begin
// reg_read_data_1 = reg_array[reg_read_addr_1];
// end
// end
assign reg_read_data_1 = ( reg_read_addr_1 == 0)? 15'b0 : reg_array[reg_read_addr_1];
//read port 2
// always @ (*) begin
// if( reg_read_addr_2 == 0) begin
// reg_read_data_2 = 15'b0;
// end
// else begin
// reg_read_data_2 = reg_array[reg_read_addr_2];
// end
// end
assign reg_read_data_2 = ( reg_read_addr_2 == 0)? 15'b0 : reg_array[reg_read_addr_2];
 
endmodule
/rtl/hazard_detection_unit.v
0,0 → 1,58
/***************************************************
* Module: hazard_detection_unit
* Project: mips_16
* Author: fzy
* Description:
* Data Hazard detection. if there is a RAW hazard, it will stall the pipeline.
*
* * Method: It compare the source register of the instruction in ID_stage
* and it's previous 3 instructions' destination register. If
* the source register is equal to any of the three destination regs
* and not equals to zero, the Hazard Detction Unit will assert
* pipeline_stall signal. That signal will freeze the IF & ID stage,
* and insert bubbles into EX stage. When the hazard instruction
* was flushed out of the pipeline, pipeline_stall signal will
* be canceled.
*
* Revise history:
*
***************************************************/
module hazard_detection_unit
(
input [2:0] decoding_op_src1, //ID stage source_1 register number
input [2:0] decoding_op_src2, //ID stage source_2 register number
input [2:0] ex_op_dest, //EX stage destinaton register number
input [2:0] mem_op_dest, //MEM stage destinaton register number
input [2:0] wb_op_dest, //WB stage destinaton register number
output reg pipeline_stall_n // Active low
);
always @ (*) begin
pipeline_stall_n = 1;
if( decoding_op_src1 != 0 &&
(
decoding_op_src1 == ex_op_dest ||
decoding_op_src1 == mem_op_dest ||
decoding_op_src1 == wb_op_dest
)
)
pipeline_stall_n = 0;
if( decoding_op_src2 != 0 &&
(
decoding_op_src2 == ex_op_dest ||
decoding_op_src2 == mem_op_dest ||
decoding_op_src2 == wb_op_dest
)
)
pipeline_stall_n = 0;
end
endmodule
/rtl/data_mem.v
0,0 → 1,40
/***************************************************
* Module: data_mem
* Project: mips_16
* Author: fzy
* Description:
* a ram implementation, 16bit word width, address width can be configured be user
* further will be able to read external memory
*
* Revise history:
*
***************************************************/
`timescale 1ns/1ps
`include "mips_16_defs.v"
module data_mem
(
input clk,
// address input, shared by read and write port
input [15:0] mem_access_addr,
// write port
input [15:0] mem_write_data,
input mem_write_en,
// read port
output [15:0] mem_read_data
);
 
 
reg [15:0] ram [(2**`DATA_MEM_ADDR_WIDTH)-1:0];
 
wire [`DATA_MEM_ADDR_WIDTH-1 : 0] ram_addr = mem_access_addr[`DATA_MEM_ADDR_WIDTH-1 : 0];
 
always @(posedge clk)
if (mem_write_en)
ram[ram_addr] <= mem_write_data;
 
assign mem_read_data = ram[ram_addr];
endmodule
/rtl/mips_16_core_top.v
0,0 → 1,126
/***************************************************
* Module: mips_16_core_top
* Project: mips_16
* Author: fzy
* Description:
* top module of mips_16 cpu core. Technical details:
* 1. 16-bit data width
* 2. classic 5-stage static pipeline, 1 branch delay slot, theoretical CPI is 1.0
* 3. pipeline is able to detect and prevent RAW hazards, no forwarding logic
* 4. 8 general purpose register (reg 0 is special, according to mips architecture)
* 5. up to now supports 13 instrcutions, see ./doc/instruction_set.txt for details
*
* Revise history:
*
***************************************************/
`timescale 1ns/1ps
`include "mips_16_defs.v"
module mips_16_core_top
(
input clk,
input rst,
 
output [`PC_WIDTH-1:0] pc
);
wire pipeline_stall_n ;
wire [5:0] branch_offset_imm;
wire branch_taken;
wire [15:0] instruction;
wire [56:0] ID_pipeline_reg_out;
wire [37:0] EX_pipeline_reg_out;
wire [36:0] MEM_pipeline_reg_out;
wire [2:0] reg_read_addr_1; // register file read port 1 address
wire [2:0] reg_read_addr_2; // register file read port 2 address
wire [15:0] reg_read_data_1; // register file read port 1 data
wire [15:0] reg_read_data_2; // register file read port 2 data
wire [2:0] decoding_op_src1; //source_1 register number
wire [2:0] decoding_op_src2; //source_2 register number
wire [2:0] ex_op_dest; //EX stage destinaton register number
wire [2:0] mem_op_dest; //MEM stage destinaton register number
wire [2:0] wb_op_dest; //WB stage destinaton register number
wire reg_write_en;
wire [2:0] reg_write_dest;
wire [15:0] reg_write_data;
IF_stage IF_stage_inst (
.clk (clk),
.rst (rst),
.instruction_fetch_en (pipeline_stall_n),
.branch_offset_imm (branch_offset_imm),
.branch_taken (branch_taken),
.pc (pc),
.instruction (instruction)
);
ID_stage ID_stage_inst (
.clk (clk),
.rst (rst),
.instruction_decode_en (pipeline_stall_n),
.pipeline_reg_out (ID_pipeline_reg_out),
.instruction (instruction),
.branch_offset_imm (branch_offset_imm),
.branch_taken (branch_taken),
.reg_read_addr_1 (reg_read_addr_1), //
.reg_read_addr_2 (reg_read_addr_2), //
.reg_read_data_1 (reg_read_data_1), //
.reg_read_data_2 (reg_read_data_2), //
.decoding_op_src1 (decoding_op_src1),
.decoding_op_src2 (decoding_op_src2)
);
EX_stage EX_stage_inst (
.clk (clk),
.rst (rst),
.pipeline_reg_in (ID_pipeline_reg_out),
.pipeline_reg_out (EX_pipeline_reg_out),
.ex_op_dest (ex_op_dest)
);
MEM_stage MEM_stage_inst (
.clk (clk),
.rst (rst),
.pipeline_reg_in (EX_pipeline_reg_out),
.pipeline_reg_out (MEM_pipeline_reg_out),
.mem_op_dest (mem_op_dest)
);
WB_stage WB_stage_inst (
.pipeline_reg_in (MEM_pipeline_reg_out),
.reg_write_en (reg_write_en),
.reg_write_dest (reg_write_dest),
.reg_write_data (reg_write_data),
.wb_op_dest (wb_op_dest)
);
register_file register_file_inst (
.clk (clk),
.rst (rst),
.reg_write_en (reg_write_en),
.reg_write_dest (reg_write_dest),
.reg_write_data (reg_write_data),
.reg_read_addr_1 (reg_read_addr_1),
.reg_read_data_1 (reg_read_data_1),
.reg_read_addr_2 (reg_read_addr_2),
.reg_read_data_2 (reg_read_data_2)
);
hazard_detection_unit hazard_detection_unit_inst (
.decoding_op_src1 (decoding_op_src1),
.decoding_op_src2 (decoding_op_src2),
.ex_op_dest (ex_op_dest),
.mem_op_dest (mem_op_dest),
.wb_op_dest (wb_op_dest),
.pipeline_stall_n (pipeline_stall_n)
);
endmodule
 
 
 
 
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.