More tests, also preliminary control unit
parent
11d4dab9cd
commit
e4a3a9ca66
|
@ -0,0 +1,9 @@
|
||||||
|
`define ALU_ADD 0
|
||||||
|
`define ALU_AND 1
|
||||||
|
`define ALU_OR 2
|
||||||
|
`define ALU_XOR 3
|
||||||
|
`define ALU_SLT 4
|
||||||
|
`define ALU_SUB 5
|
||||||
|
`define ALU_DIV 6
|
||||||
|
`define ALU_MUL 7
|
||||||
|
`define ALU_NOR 8
|
|
@ -0,0 +1,131 @@
|
||||||
|
`define OP_SPECIAL 6'b000000
|
||||||
|
`define OP_SPECIAL2 6'b011100
|
||||||
|
|
||||||
|
`define OP_ADDI 6'b001000 // addi rt, rs, imm ; rt = rs + imm
|
||||||
|
`define OP_ADDIU 6'b001001 // addiu rt, rs, imm ; rt = rs + imm
|
||||||
|
`define OP_ANDI 6'b001100 // andi rt, rs, imm ; rt = rs & imm
|
||||||
|
`define OP_ORI 6'b001101
|
||||||
|
`define OP_XORI 6'b001110
|
||||||
|
`define OP_SLTI 6'b001010
|
||||||
|
`define OP_SLTIU 6'b001011
|
||||||
|
|
||||||
|
`define OP_LB 6'b100000
|
||||||
|
`define OP_LH 6'b100001
|
||||||
|
`define OP_LBU 6'b100100
|
||||||
|
`define OP_LHU 6'b100101
|
||||||
|
`define OP_LW 6'b100011 // lw rt, imm(rs) ; rt = [rs+imm]
|
||||||
|
`define OP_SW 6'b101011 // sw rt, imm(rs) ; [rs + imm] = rt
|
||||||
|
|
||||||
|
// Special 0
|
||||||
|
`define FUNCT_ADD 6'b100000
|
||||||
|
`define FUNCT_ADDU 6'b100001
|
||||||
|
`define FUNCT_AND 6'b100100
|
||||||
|
`define FUNCT_DIV 6'b011010
|
||||||
|
`define FUNCT_DIVU 6'b011011
|
||||||
|
`define FUNCT_MULT 6'b011000
|
||||||
|
`define FUNCT_MULTU 6'b011001
|
||||||
|
`define FUNCT_NOR 6'b100111
|
||||||
|
`define FUNCT_OR 6'b100101
|
||||||
|
`define FUNCT_SLT 6'b101010
|
||||||
|
`define FUNCT_SUB 6'b100010
|
||||||
|
`define FUNCT_SUBU 6'b100011
|
||||||
|
`define FUNCT_XOR 6'b100110
|
||||||
|
|
||||||
|
// Special 2
|
||||||
|
//`define FUNCT_CLO 6'b100001
|
||||||
|
//`define FUNCT_CLZ 6'b100000
|
||||||
|
//`define FUNCT_MADD 6'b000000
|
||||||
|
//`define FUNCT_MADDU 6'b000001
|
||||||
|
//`define FUNCT_MSUB 6'b000100
|
||||||
|
//`define FUNCT_MSUBU 6'b000101
|
||||||
|
//`define FUNCT_MUL 6'b000010
|
||||||
|
|
||||||
|
`include "defines.v"
|
||||||
|
|
||||||
|
module qm_control(
|
||||||
|
/// Instruction from the decode stage
|
||||||
|
input wire [5:0] opcode,
|
||||||
|
input wire [5:0] funct,
|
||||||
|
|
||||||
|
/// Control lines to the pipeline stages
|
||||||
|
// Mux selecting the destination register for the register writeback
|
||||||
|
// 0 - RT
|
||||||
|
// 1 - RD
|
||||||
|
output wire reg_destination,
|
||||||
|
// Mux selecting the source of the ALU B operand
|
||||||
|
// 0 - Value of RT register
|
||||||
|
// 1 - instruction Imediate part
|
||||||
|
output wire alu_source,
|
||||||
|
// ALU Control signal, select ALU operation
|
||||||
|
output wire [3:0] alu_control,
|
||||||
|
// Memory write enable signal
|
||||||
|
output wire mem_write,
|
||||||
|
// Mux selecting the source of the data for the register writeback
|
||||||
|
// 0 - output of ALU
|
||||||
|
// 1 - data read from memory
|
||||||
|
output wire reg_wsource,
|
||||||
|
// Register writeback enable signal
|
||||||
|
output wire reg_write
|
||||||
|
);
|
||||||
|
|
||||||
|
always @(opcode, funct) begin
|
||||||
|
case (opcode)
|
||||||
|
`OP_SPECIAL: begin
|
||||||
|
reg_destination <= 1;
|
||||||
|
alu_source <= 0;
|
||||||
|
mem_write <= 0;
|
||||||
|
reg_wsource <= 0;
|
||||||
|
reg_write <= 1;
|
||||||
|
case (funct)
|
||||||
|
`FUNCT_ADD: <= `ALU_ADD;
|
||||||
|
`FUNCT_ADDU: <= `ALU_ADD;
|
||||||
|
`FUNCT_AND: <= `ALU_AND;
|
||||||
|
`FUNCT_DIV: <= `ALU_DIV;
|
||||||
|
`FUNCT_DIVU: <= `ALU_DIV;
|
||||||
|
`FUNCT_MULT: <= `ALU_MUL;
|
||||||
|
`FUNCT_MULTU: <= `ALU_MUL;
|
||||||
|
`FUNCT_NOR: <= `ALU_NOR
|
||||||
|
`FUNCT_OR: <= `ALU_OR;
|
||||||
|
`FUNCT_SLT: <= `ALU_SLT;
|
||||||
|
`FUNCT_SUB: <= `ALU_SUB;
|
||||||
|
`FUNCT_SUBU: <= `ALU_SUB;
|
||||||
|
`FUNCT_XOR: <= `ALU_XOR;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
`OP_LW: begin
|
||||||
|
reg_destination <= 0;
|
||||||
|
alu_source <= 1;
|
||||||
|
alu_control <= 0;
|
||||||
|
mem_write <= 0;
|
||||||
|
reg_wsource <= 1;
|
||||||
|
reg_write <= 1;
|
||||||
|
end
|
||||||
|
`OP_SW: begin
|
||||||
|
reg_destination <= 0;
|
||||||
|
alu_source <= 1;
|
||||||
|
alu_control <= 0;
|
||||||
|
mem_write <= 1;
|
||||||
|
reg_wsource <= 0;
|
||||||
|
reg_write <= 0;
|
||||||
|
end
|
||||||
|
6'b001???: // all immediate arith/logic
|
||||||
|
default: begin
|
||||||
|
reg_destination <= 0;
|
||||||
|
alu_source <= 0;
|
||||||
|
mem_write <= 0;
|
||||||
|
reg_wsource <= 0;
|
||||||
|
reg_write <= 0;
|
||||||
|
case (opcode)
|
||||||
|
`OP_ADDI: alu_control <= `ALU_ADD;
|
||||||
|
`OP_ADDIU: alu_control <= `ALU_ADD;
|
||||||
|
`OP_ANDI: alu_control <= `ALU_AND;
|
||||||
|
`OP_ORI: alu_control <= `ALU_OR;
|
||||||
|
`OP_XORI: alu_control <= `ALU_XOR;
|
||||||
|
`OP_SLTI: alu_control <= `ALU_SLT;
|
||||||
|
`OP_SLTIU: alu_control <= `ALU_SLTIU;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -1,9 +1,29 @@
|
||||||
module qm_fetch(
|
module qm_fetch(
|
||||||
/// datapath
|
/// datapath
|
||||||
|
// input PC to assume
|
||||||
|
input wire [31:0] di_PC,
|
||||||
// output instruction register
|
// output instruction register
|
||||||
output wire [31:0] do_IR,
|
output wire [31:0] do_IR,
|
||||||
// output next pc
|
// output to next PC
|
||||||
output wire [31:0] do_NextPC
|
output wire [31:0] do_NextPC,
|
||||||
);
|
|
||||||
|
// icache connectivity
|
||||||
|
output wire [31:0] icache_address,
|
||||||
|
input wire icache_hit,
|
||||||
|
input wire icache_should_stall,
|
||||||
|
input wire [31:0] icache_data
|
||||||
|
);
|
||||||
|
|
||||||
|
assign icache_address = di_PC;
|
||||||
|
|
||||||
|
always @(*) begin
|
||||||
|
if (icache_should_stall && !icache_hit) begin
|
||||||
|
do_NextPC = di_PC;
|
||||||
|
do_IR = 0;
|
||||||
|
end else begin
|
||||||
|
do_NextPC = di_PC + 4;
|
||||||
|
do_IR = icache_data;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -76,7 +76,7 @@ always @(posedge clk) begin
|
||||||
end
|
end
|
||||||
|
|
||||||
// read condition
|
// read condition
|
||||||
always @(address, lines) begin
|
always @(*) begin
|
||||||
if (enable) begin
|
if (enable) begin
|
||||||
// is this in the RAM region?
|
// is this in the RAM region?
|
||||||
if (32'h80000000 <= address && address < 32'h90000000) begin
|
if (32'h80000000 <= address && address < 32'h90000000) begin
|
||||||
|
|
|
@ -15,12 +15,12 @@ module qm_regfile(
|
||||||
reg [31:0] rf [31:0];
|
reg [31:0] rf [31:0];
|
||||||
|
|
||||||
always @(wd3) begin
|
always @(wd3) begin
|
||||||
if (we3) begin
|
if (we3 && wa != 0) begin
|
||||||
rf[wa3] = wd3;
|
rf[wa3] = wd3;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assign rd1 = rf[ra1];
|
assign rd1 = (ra1 == 0 ? 0 : rf[ra1]);
|
||||||
assign rd2 = rf[ra2];
|
assign rd2 = (ra2 == 0 ? 0 : rf[ra2]);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
module qm_top(
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Fetch / Decode
|
||||||
|
reg [31:0] FD_IR;
|
||||||
|
reg [31:0] FD_NextPC;
|
||||||
|
|
||||||
|
// Decode / Execute
|
||||||
|
reg [31:0] DE_A;
|
||||||
|
reg [31:0] DE_B;
|
||||||
|
reg [31:0] DE_Imm;
|
||||||
|
reg [31:0] DE_IR;
|
||||||
|
|
||||||
|
wire [31:0] ICache_Address;
|
||||||
|
wire [31:0] ICache_Data;
|
||||||
|
wire ICache_Hit;
|
||||||
|
wire ICache_ShouldStall;
|
||||||
|
// ICache
|
||||||
|
qm_icache icache(
|
||||||
|
.reset(reset),
|
||||||
|
.clk(sys_clk),
|
||||||
|
|
||||||
|
.address(ICache_Address),
|
||||||
|
.data(ICache_Data),
|
||||||
|
.hit(ICache_Hit),
|
||||||
|
.stall(ICache_ShouldStall),
|
||||||
|
.enable(ICache_Enable)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fetch
|
||||||
|
wire [31:0] fetch_IR;
|
||||||
|
wire [31:0] fetch_NextPC;
|
||||||
|
qm_fetch fetch(
|
||||||
|
.di_PC(FD_NextPC),
|
||||||
|
.do_IR(fetch_IR),
|
||||||
|
.do_NextPC(fetch_NextPC),
|
||||||
|
|
||||||
|
.icache_address(ICache_Address),
|
||||||
|
.icache_hit(ICache_Hit),
|
||||||
|
.icache_should_stall(ICache_ShouldStall),
|
||||||
|
.icache_data(ICache_Data)
|
||||||
|
);
|
||||||
|
always @(posedge clk) begin
|
||||||
|
FD_IR <= fetch_IR;
|
||||||
|
FD_NextPC <= fetch_NextPC;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -9,11 +9,14 @@ obj_dir/V%.cpp: ../rtl/verilog/%.v
|
||||||
OBJS := /usr/share/verilator/include/verilated.cpp \
|
OBJS := /usr/share/verilator/include/verilated.cpp \
|
||||||
obj_dir/Vqm_decode.o \
|
obj_dir/Vqm_decode.o \
|
||||||
obj_dir/Vqm_decode__Syms.cpp \
|
obj_dir/Vqm_decode__Syms.cpp \
|
||||||
|
obj_dir/Vqm_fetch.o \
|
||||||
|
obj_dir/Vqm_fetch__Syms.cpp \
|
||||||
obj_dir/Vqm_icache.o \
|
obj_dir/Vqm_icache.o \
|
||||||
obj_dir/Vqm_icache__Syms.cpp \
|
obj_dir/Vqm_icache__Syms.cpp \
|
||||||
main.o \
|
main.o \
|
||||||
test_decode.o \
|
test_decode.o \
|
||||||
test_icache.o
|
test_icache.o \
|
||||||
|
test_fetch.o
|
||||||
|
|
||||||
test: $(OBJS)
|
test: $(OBJS)
|
||||||
g++ $(CXXFLAGS) -o test $(OBJS)
|
g++ $(CXXFLAGS) -o test $(OBJS)
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
#include "test_decode.h"
|
#include "test_decode.h"
|
||||||
#include "test_icache.h"
|
#include "test_icache.h"
|
||||||
|
#include "test_fetch.h"
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
test_decode();
|
//test_decode();
|
||||||
test_icache();
|
//test_icache();
|
||||||
|
test_fetch();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include "test_fetch.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include "Vqm_fetch.h"
|
||||||
|
|
||||||
|
void test_fetch(void)
|
||||||
|
{
|
||||||
|
Vqm_fetch *fetch = new Vqm_fetch();
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef _TEST_FETCH_H
|
||||||
|
#define _TEST_FETCH_H
|
||||||
|
|
||||||
|
void test_fetch(void);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue