Linter corrections
This commit is contained in:
parent
7aa1c6de4f
commit
0c2ada7965
101
rtl/ALU.sv
101
rtl/ALU.sv
@ -1,53 +1,54 @@
|
|||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
// N = Bit width
|
// N = Bit width
|
||||||
module ALU #(parameter N = 32)
|
module ALU #(
|
||||||
(
|
parameter integer N = 32
|
||||||
input logic[N-1:0] a,
|
) (
|
||||||
input logic[N-1:0] b,
|
input logic [N-1:0] a,
|
||||||
input logic[2:0] opcode,
|
input logic [N-1:0] b,
|
||||||
output logic[N-1:0] result,
|
input logic [ 2:0] opcode,
|
||||||
output logic[3:0] status
|
output logic [N-1:0] result,
|
||||||
|
output logic [ 3:0] status
|
||||||
);
|
);
|
||||||
logic n, z, c, v;
|
logic n, z, c, v;
|
||||||
logic opsign_comp, v_value;
|
logic opsign_comp, v_value;
|
||||||
always_comb begin
|
always_comb begin
|
||||||
// Check if the signs of the operands are equal considering substraction sign simplification over the B operand
|
// Check if the signs of the operands are equal considering substraction sign simplification over the B operand
|
||||||
opsign_comp = (a[N-1] == (b[N-1] ^ opcode[0]));
|
opsign_comp = (a[N-1] == (b[N-1] ^ opcode[0]));
|
||||||
// There is an overflow if the signs are equal and the result differ from the operation sign
|
// There is an overflow if the signs are equal and the result differ from the operation sign
|
||||||
// The overflow flag only gets assign when the operation is either a sum or a substraction
|
// The overflow flag only gets assign when the operation is either a sum or a substraction
|
||||||
v_value = opsign_comp && (result != a[N-1]);
|
v_value = opsign_comp && (result != a[N-1]);
|
||||||
case(opcode)
|
case (opcode)
|
||||||
'b000: begin // Addition
|
'b000: begin // Addition
|
||||||
{c, result} = a + b;
|
{c, result} = a + b;
|
||||||
v = v_value;
|
v = v_value;
|
||||||
end
|
end
|
||||||
'b001: begin // Substraction
|
'b001: begin // Substraction
|
||||||
{c, result} = a - b;
|
{c, result} = a - b;
|
||||||
v = v_value;
|
v = v_value;
|
||||||
end
|
end
|
||||||
'b011: begin // Or
|
'b011: begin // Or
|
||||||
result = a | b;
|
result = a | b;
|
||||||
c = 'b0;
|
c = 'b0;
|
||||||
v = 'b0;
|
v = 'b0;
|
||||||
end
|
end
|
||||||
'b010: begin // And
|
'b010: begin // And
|
||||||
result = a & b;
|
result = a & b;
|
||||||
c = 'b0;
|
c = 'b0;
|
||||||
v = 'b0;
|
v = 'b0;
|
||||||
end
|
end
|
||||||
'b101: begin // Set less than
|
'b101: begin // Set less than
|
||||||
result = a < b;
|
result = a < b;
|
||||||
c = 'b0;
|
c = 'b0;
|
||||||
v = 'b0;
|
v = 'b0;
|
||||||
end
|
end
|
||||||
default: begin
|
default: begin
|
||||||
result = 'dx;
|
result = 'dx;
|
||||||
c = 'dx;
|
c = 'dx;
|
||||||
v = 'dx;
|
v = 'dx;
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
n = result[N-1];
|
n = result[N-1];
|
||||||
z = (result == '0);
|
z = (result == '0);
|
||||||
status = {n, z, c, v};
|
status = {n, z, c, v};
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,63 +1,65 @@
|
|||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
module ALUDecoder(
|
module ALUDecoder (
|
||||||
input logic opcode_5,
|
input logic opcode_5,
|
||||||
input logic[2:0] funct_3,
|
input logic [2:0] funct_3,
|
||||||
input logic funct_7_5,
|
input logic funct_7_5,
|
||||||
input logic[1:0] alu_op,
|
input logic [1:0] alu_op,
|
||||||
output logic[2:0] alu_ctrl,
|
output logic [2:0] alu_ctrl,
|
||||||
output logic branch_neg
|
output logic branch_neg
|
||||||
);
|
);
|
||||||
always_comb begin
|
always_comb begin
|
||||||
casex({alu_op, funct_3, opcode_5, funct_7_5})
|
casex ({
|
||||||
'b00xxxxx: begin
|
alu_op, funct_3, opcode_5, funct_7_5
|
||||||
alu_ctrl = 'b000; // lw sw
|
})
|
||||||
branch_neg = 'dx;
|
'b00xxxxx: begin
|
||||||
end
|
alu_ctrl = 'b000; // lw sw
|
||||||
'b01000xx: begin
|
branch_neg = 'dx;
|
||||||
alu_ctrl = 'b001; // beq
|
end
|
||||||
branch_neg = 1;
|
'b01000xx: begin
|
||||||
end
|
alu_ctrl = 'b001; // beq
|
||||||
'b01100xx: begin
|
branch_neg = 1;
|
||||||
alu_ctrl = 'b101; // blt
|
end
|
||||||
branch_neg = 0;
|
'b01100xx: begin
|
||||||
end
|
alu_ctrl = 'b101; // blt
|
||||||
'b01101xx: begin
|
branch_neg = 0;
|
||||||
alu_ctrl = 'b101; // bge
|
end
|
||||||
branch_neg = 1;
|
'b01101xx: begin
|
||||||
end
|
alu_ctrl = 'b101; // bge
|
||||||
'b1000000: begin
|
branch_neg = 1;
|
||||||
alu_ctrl = 'b000; // add
|
end
|
||||||
branch_neg = 'dx;
|
'b1000000: begin
|
||||||
end
|
alu_ctrl = 'b000; // add
|
||||||
'b1000001: begin
|
branch_neg = 'dx;
|
||||||
alu_ctrl = 'b000; // add
|
end
|
||||||
branch_neg = 'dx;
|
'b1000001: begin
|
||||||
end
|
alu_ctrl = 'b000; // add
|
||||||
'b1000010: begin
|
branch_neg = 'dx;
|
||||||
alu_ctrl = 'b000; // add
|
end
|
||||||
branch_neg = 'dx;
|
'b1000010: begin
|
||||||
end
|
alu_ctrl = 'b000; // add
|
||||||
'b1000011: begin
|
branch_neg = 'dx;
|
||||||
alu_ctrl = 'b001; // sub
|
end
|
||||||
branch_neg = 'dx;
|
'b1000011: begin
|
||||||
end
|
alu_ctrl = 'b001; // sub
|
||||||
'b10010xx: begin
|
branch_neg = 'dx;
|
||||||
alu_ctrl = 'b101; // slt
|
end
|
||||||
branch_neg = 'dx;
|
'b10010xx: begin
|
||||||
end
|
alu_ctrl = 'b101; // slt
|
||||||
'b10110xx: begin
|
branch_neg = 'dx;
|
||||||
alu_ctrl = 'b000; // or
|
end
|
||||||
branch_neg = 'dx;
|
'b10110xx: begin
|
||||||
end
|
alu_ctrl = 'b000; // or
|
||||||
'b10111xx: begin
|
branch_neg = 'dx;
|
||||||
alu_ctrl = 'b000; // and
|
end
|
||||||
branch_neg = 'dx;
|
'b10111xx: begin
|
||||||
end
|
alu_ctrl = 'b000; // and
|
||||||
default: begin
|
branch_neg = 'dx;
|
||||||
alu_ctrl = 'dx;
|
end
|
||||||
branch_neg = 'dx;
|
default: begin
|
||||||
end
|
alu_ctrl = 'dx;
|
||||||
endcase
|
branch_neg = 'dx;
|
||||||
end
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,88 +1,92 @@
|
|||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
module CacheController #(
|
module CacheController #(
|
||||||
parameter ADDR_SIZE = 32,
|
parameter int ADDR_SIZE = 32,
|
||||||
parameter NUM_SETS = 16,
|
parameter int NUM_SETS = 16,
|
||||||
parameter NUM_WAYS = 4,
|
parameter int NUM_WAYS = 4,
|
||||||
parameter BLOCK_SIZE = 32
|
parameter int BLOCK_SIZE = 32
|
||||||
) (
|
) (
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic[ADDR_SIZE - 1:0] addr,
|
input logic [ADDR_SIZE - 1:0] addr,
|
||||||
input logic write_enable,
|
input logic write_enable,
|
||||||
input logic replace_way,
|
input logic replace_way,
|
||||||
input logic[NUM_WAYS - 1:0] hits,
|
input logic [NUM_WAYS - 1:0] hits,
|
||||||
input logic[NUM_WAYS - 1:0] valid_flags,
|
input logic [NUM_WAYS - 1:0] valid_flags,
|
||||||
output logic[SET_SIZE - 1:0] set,
|
output logic [SetSize - 1:0] set,
|
||||||
output logic[TAG_SIZE - 1:0] tag,
|
output logic [TagSize - 1:0] tag,
|
||||||
output logic[WAY_SIZE - 1:0] way,
|
output logic [WaySize - 1:0] way,
|
||||||
output logic hit,
|
output logic hit,
|
||||||
output logic cru_enable
|
output logic cru_enable
|
||||||
);
|
);
|
||||||
localparam NUM_BLOCK_BYTES = BLOCK_SIZE / 4;
|
localparam int NumBlockBytes = BLOCK_SIZE / 4;
|
||||||
localparam BYTE_OFFSET_SIZE = $clog2(NUM_BLOCK_BYTES);
|
localparam int ByteOffsetSize = $clog2(NumBlockBytes);
|
||||||
localparam SET_SIZE = $clog2(NUM_SETS);
|
localparam int SetSize = $clog2(NUM_SETS);
|
||||||
localparam TAG_SIZE = ADDR_SIZE - SET_SIZE - BYTE_OFFSET_SIZE;
|
localparam int TagSize = ADDR_SIZE - SetSize - ByteOffsetSize;
|
||||||
localparam WAY_SIZE = $clog2(NUM_WAYS);
|
localparam int WaySize = $clog2(NUM_WAYS);
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic[BYTE_OFFSET_SIZE - 1:0] byte_offset;
|
|
||||||
logic[SET_SIZE - 1:0] set;
|
|
||||||
logic[TAG_SIZE - 1:0] tag;
|
|
||||||
} cache_addr;
|
|
||||||
|
|
||||||
typedef enum logic[1:0] {
|
|
||||||
READ = 'b00,
|
|
||||||
WRITE_UNVALID = 'b10,
|
|
||||||
REPLACE = 'b11
|
|
||||||
} cache_state;
|
|
||||||
|
|
||||||
cache_addr packed_addr;
|
|
||||||
cache_state state;
|
|
||||||
|
|
||||||
logic[WAY_SIZE - 1:0] valid_encode, next_unvalid_way;
|
|
||||||
PriorityEncoder #(.N(WAY_SIZE)) valid_flags_encoder(valid_flags, valid_encode, valid_flags_encoder_valid);
|
|
||||||
PriorityEncoder #(.N(WAY_SIZE)) read_way_encoder(hits, read_way, read_way_encoder_valid);
|
|
||||||
|
|
||||||
logic valid;
|
typedef struct packed {
|
||||||
always_comb begin
|
logic [ByteOffsetSize - 1:0] byte_offset;
|
||||||
packed_addr = cache_addr'(addr);
|
logic [SetSize - 1:0] set;
|
||||||
set = packed_addr.set;
|
logic [TagSize - 1:0] tag;
|
||||||
tag = packed_addr.tag;
|
} cache_addr_t;
|
||||||
|
|
||||||
hit = |hits;
|
|
||||||
valid = &valid_flags;
|
|
||||||
|
|
||||||
state = cache_state'{write_enable, valid};
|
typedef enum logic [1:0] {
|
||||||
|
READ = 'b00,
|
||||||
|
WRITE_UNVALID = 'b10,
|
||||||
|
REPLACE = 'b11
|
||||||
|
} cache_state_t;
|
||||||
|
|
||||||
case(state)
|
cache_addr packed_addr;
|
||||||
READ: begin
|
cache_state_t state;
|
||||||
cru_enable = 0;
|
|
||||||
if (read_way_encoder_valid)
|
|
||||||
way = read_way;
|
|
||||||
else
|
|
||||||
way = 'd0;
|
|
||||||
end
|
|
||||||
WRITE_UNVALID: begin
|
|
||||||
cru_enable = 0;
|
|
||||||
way = next_unvalid_way;
|
|
||||||
end
|
|
||||||
REPLACE: begin
|
|
||||||
cru_enable = 1;
|
|
||||||
way = replace_way;
|
|
||||||
end
|
|
||||||
default: begin
|
|
||||||
cru_enable = 0;
|
|
||||||
way = 'dx;
|
|
||||||
end
|
|
||||||
endcase
|
|
||||||
|
|
||||||
if (valid_flags_encoder_valid)
|
|
||||||
next_unvalid_way = valid_encode + 'd1;
|
|
||||||
else
|
|
||||||
next_unvalid_way = 'd0;
|
|
||||||
end
|
|
||||||
/*
|
|
||||||
always_ff @(posedge clk) begin
|
|
||||||
|
|
||||||
end*/
|
logic [WaySize - 1:0] valid_encode, next_unvalid_way;
|
||||||
|
PriorityEncoder #(
|
||||||
|
.N(WaySize)
|
||||||
|
) valid_flags_encoder (
|
||||||
|
.data_in(valid_flags),
|
||||||
|
.data_out(valid_encode),
|
||||||
|
.valid(valid_flags_encoder_valid)
|
||||||
|
);
|
||||||
|
PriorityEncoder #(
|
||||||
|
.N(WaySize)
|
||||||
|
) read_way_encoder (
|
||||||
|
.data_in(hits),
|
||||||
|
.data_out(read_way),
|
||||||
|
.valid(read_way_encoder_valid)
|
||||||
|
);
|
||||||
|
|
||||||
|
logic valid;
|
||||||
|
always_comb begin
|
||||||
|
packed_addr = cache_addr'(addr);
|
||||||
|
set = packed_addr.set;
|
||||||
|
tag = packed_addr.tag;
|
||||||
|
|
||||||
|
hit = |hits;
|
||||||
|
valid = &valid_flags;
|
||||||
|
|
||||||
|
state = cache_state_t'{write_enable, valid};
|
||||||
|
|
||||||
|
case (state)
|
||||||
|
READ: begin
|
||||||
|
cru_enable = 0;
|
||||||
|
if (read_way_encoder_valid) way = read_way;
|
||||||
|
else way = 'd0;
|
||||||
|
end
|
||||||
|
WRITE_UNVALID: begin
|
||||||
|
cru_enable = 0;
|
||||||
|
way = next_unvalid_way;
|
||||||
|
end
|
||||||
|
REPLACE: begin
|
||||||
|
cru_enable = 1;
|
||||||
|
way = replace_way;
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
cru_enable = 0;
|
||||||
|
way = 'dx;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
|
||||||
|
if (valid_flags_encoder_valid) next_unvalid_way = valid_encode + 'd1;
|
||||||
|
else next_unvalid_way = 'd0;
|
||||||
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,58 +1,59 @@
|
|||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
module CacheMemory #(
|
module CacheMemory #(
|
||||||
parameter ADDR_SIZE = 32,
|
parameter int ADDR_SIZE = 32,
|
||||||
parameter NUM_SETS = 16,
|
parameter int NUM_SETS = 16,
|
||||||
parameter NUM_WAYS = 4,
|
parameter int NUM_WAYS = 4,
|
||||||
parameter BLOCK_SIZE = 32
|
parameter int BLOCK_SIZE = 32
|
||||||
)(
|
) (
|
||||||
input logic clk, rst,
|
input logic clk,
|
||||||
input logic[WAY_SIZE - 1:0] way,
|
rst,
|
||||||
input logic[SET_SIZE - 1:0] set,
|
input logic [WaySize - 1:0] way,
|
||||||
input logic[TAG_SIZE - 1:0] tag,
|
input logic [SetSize - 1:0] set,
|
||||||
|
input logic [TagSize - 1:0] tag,
|
||||||
input logic write_enable,
|
input logic write_enable,
|
||||||
input logic[BLOCK_SIZE - 1:0] write_data,
|
input logic [BLOCK_SIZE - 1:0] write_data,
|
||||||
output logic[BLOCK_SIZE - 1:0] read_data,
|
output logic [BLOCK_SIZE - 1:0] read_data,
|
||||||
output logic[NUM_WAYS - 1:0] hits,
|
output logic [NUM_WAYS - 1:0] hits,
|
||||||
output logic[NUM_WAYS - 1:0] valid_flags
|
output logic [NUM_WAYS - 1:0] valid_flags
|
||||||
);
|
);
|
||||||
localparam NUM_BLOCK_BYTES = BLOCK_SIZE / 4;
|
localparam int NumBlockBytes = BLOCK_SIZE / 4;
|
||||||
localparam BYTE_OFFSET_SIZE = $clog2(NUM_BLOCK_BYTES);
|
localparam int ByteOffsetSize = $clog2(NumBlockBytes);
|
||||||
localparam WAY_SIZE = $clog2(NUM_WAYS);
|
localparam int WaySize = $clog2(NUM_WAYS);
|
||||||
localparam SET_SIZE = $clog2(NUM_SETS);
|
localparam int SetSize = $clog2(NUM_SETS);
|
||||||
localparam TAG_SIZE = ADDR_SIZE - SET_SIZE - BYTE_OFFSET_SIZE;
|
localparam int TagSize = ADDR_SIZE - SetSize - ByteOffsetSize;
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
logic[BLOCK_SIZE - 1:0] data;
|
logic [BLOCK_SIZE - 1:0] data;
|
||||||
logic[TAG_SIZE - 1:0] tag;
|
logic [TagSize - 1:0] tag;
|
||||||
logic valid;
|
logic valid;
|
||||||
} cache_line;
|
} cache_line_t;
|
||||||
|
|
||||||
typedef cache_line[NUM_SETS - 1:0] cache_way;
|
typedef cache_line [NUM_SETS - 1:0] cache_way;
|
||||||
cache_way[NUM_WAYS - 1:0] ways;
|
cache_way [NUM_WAYS - 1:0] ways;
|
||||||
|
|
||||||
assign read_data = ways[way][set].data;
|
assign read_data = ways[way][set].data;
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (rst) begin
|
if (rst) begin
|
||||||
// Reset valid flags
|
// Reset valid flags
|
||||||
for (int i = 0; i < NUM_WAYS; i++) begin
|
for (int i = 0; i < NUM_WAYS; i++) begin
|
||||||
for (int j = 0; j < NUM_SETS; j++) begin
|
for (int j = 0; j < NUM_SETS; j++) begin
|
||||||
ways[i][j].data <= 'dx;
|
ways[i][j].data <= 'dx;
|
||||||
ways[i][j].tag <= 'dx;
|
ways[i][j].tag <= 'dx;
|
||||||
ways[i][j].valid <= 0;
|
ways[i][j].valid <= 0;
|
||||||
end
|
|
||||||
end
|
|
||||||
end else if (write_enable) begin
|
|
||||||
ways[way][set].data <= write_data;
|
|
||||||
ways[way][set].tag <= tag;
|
|
||||||
ways[way][set].valid <= 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
always_comb begin
|
|
||||||
for (int i = 0; i < NUM_WAYS; i++) begin
|
|
||||||
valid_flags[i] = ways[i][set].valid;
|
|
||||||
hits[i] = ways[i][set].valid && (tag == ways[i][set].tag);
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end else if (write_enable) begin
|
||||||
|
ways[way][set].data <= write_data;
|
||||||
|
ways[way][set].tag <= tag;
|
||||||
|
ways[way][set].valid <= 1;
|
||||||
end
|
end
|
||||||
endmodule
|
end
|
||||||
|
always_comb begin
|
||||||
|
for (int i = 0; i < NUM_WAYS; i++) begin
|
||||||
|
valid_flags[i] = ways[i][set].valid;
|
||||||
|
hits[i] = ways[i][set].valid && (tag == ways[i][set].tag);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
@ -2,39 +2,39 @@
|
|||||||
|
|
||||||
import rv32i_defs::*;
|
import rv32i_defs::*;
|
||||||
|
|
||||||
module ControlUnit
|
module ControlUnit (
|
||||||
(
|
input logic [6:0] opcode,
|
||||||
input logic[6:0] opcode,
|
input logic [2:0] funct_3,
|
||||||
input logic[2:0] funct_3,
|
input logic [6:0] funct_7,
|
||||||
input logic[6:0] funct_7,
|
output logic [1:0] result_src,
|
||||||
output logic[1:0] result_src,
|
|
||||||
output logic mem_write,
|
output logic mem_write,
|
||||||
output logic[2:0] alu_ctrl,
|
output logic [2:0] alu_ctrl,
|
||||||
output logic alu_src,
|
output logic alu_src,
|
||||||
output logic[1:0] imm_src,
|
output logic [1:0] imm_src,
|
||||||
output logic reg_write,
|
output logic reg_write,
|
||||||
output logic jump,
|
output logic jump,
|
||||||
output logic branch, branch_alu_neg
|
output logic branch,
|
||||||
|
branch_alu_neg
|
||||||
);
|
);
|
||||||
logic[1:0] alu_op;
|
logic [1:0] alu_op;
|
||||||
MainDecoder main_decoder(
|
MainDecoder main_decoder (
|
||||||
opcode,
|
.opcode(opcode),
|
||||||
branch,
|
.branch(branch),
|
||||||
jump,
|
.jump(jump),
|
||||||
result_src,
|
.result_src(result_src),
|
||||||
mem_write,
|
.mem_write(mem_write),
|
||||||
alu_src,
|
.alu_src(alu_src),
|
||||||
imm_src,
|
.imm_src(imm_src),
|
||||||
reg_write,
|
.reg_write(reg_write),
|
||||||
alu_op
|
.alu_op(alu_op)
|
||||||
);
|
);
|
||||||
|
|
||||||
ALUDecoder alu_decoder(
|
ALUDecoder alu_decoder (
|
||||||
opcode[5],
|
.opcode_5(opcode[5]),
|
||||||
funct_3,
|
.funct_3(funct_3),
|
||||||
funct_7[5],
|
.funct_7_5(funct_7[5]),
|
||||||
alu_op,
|
.alu_op(alu_op),
|
||||||
alu_ctrl,
|
.alu_ctrl(alu_ctrl),
|
||||||
branch_alu_neg
|
.branch_neg(branch_alu_neg)
|
||||||
);
|
);
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
module Extend
|
module Extend (
|
||||||
(
|
input logic [ 1:0] imm_src,
|
||||||
input logic[1:0] imm_src,
|
input logic [31:7] instr,
|
||||||
input logic[31:7] instr,
|
output logic [31:0] imm_ext
|
||||||
output logic[31:0] imm_ext
|
|
||||||
);
|
);
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case(imm_src)
|
case (imm_src)
|
||||||
'd0: imm_ext = {{20{instr[31]}}, instr[31:20]}; // Type I
|
'd0: imm_ext = {{20{instr[31]}}, instr[31:20]}; // Type I
|
||||||
'd1: imm_ext = {{20{instr[31]}}, instr[31:25], instr[11:7]}; // Type S
|
'd1: imm_ext = {{20{instr[31]}}, instr[31:25], instr[11:7]}; // Type S
|
||||||
'd2: imm_ext = {{20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0}; // Type B
|
'd2: imm_ext = {{20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0}; // Type B
|
||||||
'd3: imm_ext = {{12{instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0}; // Type J
|
'd3: imm_ext = {{12{instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0}; // Type J
|
||||||
endcase
|
default: imm_ext = 'dx;
|
||||||
end
|
endcase
|
||||||
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -2,45 +2,52 @@
|
|||||||
|
|
||||||
module HazardUnit (
|
module HazardUnit (
|
||||||
input logic rst,
|
input logic rst,
|
||||||
execute_pc_src, execute_result_src_0,
|
execute_pc_src,
|
||||||
memory_reg_write, writeback_reg_write,
|
execute_result_src_0,
|
||||||
input logic[4:0] decode_rs_1, decode_rs_2,
|
memory_reg_write,
|
||||||
execute_rs_1, execute_rs_2,
|
writeback_reg_write,
|
||||||
execute_rd, memory_rd, writeback_rd,
|
input logic [4:0] decode_rs_1,
|
||||||
output logic fetch_stall, decode_stall,
|
decode_rs_2,
|
||||||
decode_flush, execute_flush,
|
execute_rs_1,
|
||||||
output logic[1:0] execute_forward_a, execute_forward_b
|
execute_rs_2,
|
||||||
|
execute_rd,
|
||||||
|
memory_rd,
|
||||||
|
writeback_rd,
|
||||||
|
output logic fetch_stall,
|
||||||
|
decode_stall,
|
||||||
|
decode_flush,
|
||||||
|
execute_flush,
|
||||||
|
output logic [1:0] execute_forward_a,
|
||||||
|
execute_forward_b
|
||||||
);
|
);
|
||||||
logic lw_stall;
|
logic lw_stall;
|
||||||
always_comb begin
|
always_comb begin
|
||||||
if (rst) begin
|
if (rst) begin
|
||||||
fetch_stall = 0;
|
fetch_stall = 0;
|
||||||
decode_stall = 0;
|
decode_stall = 0;
|
||||||
decode_flush = 1;
|
decode_flush = 1;
|
||||||
execute_flush = 1;
|
execute_flush = 1;
|
||||||
execute_forward_a = 0;
|
execute_forward_a = 0;
|
||||||
execute_forward_b = 0;
|
execute_forward_b = 0;
|
||||||
end else begin
|
end else begin
|
||||||
if (((execute_rs_1 == memory_rd) & memory_reg_write) & (execute_rs_1 != 0))
|
if (((execute_rs_1 == memory_rd) & memory_reg_write) & (execute_rs_1 != 0))
|
||||||
execute_forward_a = 'b10;
|
execute_forward_a = 'b10;
|
||||||
else if (((execute_rs_1 == writeback_rd) & writeback_reg_write) & (execute_rs_1 != 0))
|
else if (((execute_rs_1 == writeback_rd) & writeback_reg_write) & (execute_rs_1 != 0))
|
||||||
execute_forward_a = 'b01;
|
execute_forward_a = 'b01;
|
||||||
else
|
else execute_forward_a = 'b00;
|
||||||
execute_forward_a = 'b00;
|
|
||||||
|
if (((execute_rs_2 == memory_rd) & memory_reg_write) & (execute_rs_2 != 0))
|
||||||
if (((execute_rs_2 == memory_rd) & memory_reg_write) & (execute_rs_2 != 0))
|
execute_forward_b = 'b10;
|
||||||
execute_forward_b = 'b10;
|
else if (((execute_rs_2 == writeback_rd) & writeback_reg_write) & (execute_rs_2 != 0))
|
||||||
else if (((execute_rs_2 == writeback_rd) & writeback_reg_write) & (execute_rs_2 != 0))
|
execute_forward_b = 'b01;
|
||||||
execute_forward_b = 'b01;
|
else execute_forward_b = 'b00;
|
||||||
else
|
|
||||||
execute_forward_b = 'b00;
|
lw_stall = execute_result_src_0 & ((decode_rs_1 == execute_rd) | (decode_rs_2 == execute_rd));
|
||||||
|
fetch_stall = lw_stall;
|
||||||
lw_stall = execute_result_src_0 & ((decode_rs_1 == execute_rd) | (decode_rs_2 == execute_rd));
|
decode_stall = lw_stall;
|
||||||
fetch_stall = lw_stall;
|
|
||||||
decode_stall = lw_stall;
|
decode_flush = execute_pc_src;
|
||||||
|
execute_flush = lw_stall | execute_pc_src;
|
||||||
decode_flush = execute_pc_src;
|
|
||||||
execute_flush = lw_stall | execute_pc_src;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -2,22 +2,18 @@
|
|||||||
|
|
||||||
// N = Bit width
|
// N = Bit width
|
||||||
module InstructionMemory #(
|
module InstructionMemory #(
|
||||||
parameter N = 32,
|
parameter int N = 32,
|
||||||
parameter N_INSTR = 32,
|
parameter int N_INSTR = 32,
|
||||||
parameter BYTE_WIDTH = 8
|
parameter int BYTE_WIDTH = 8
|
||||||
)
|
) (
|
||||||
(
|
input logic [N-1:0] addr,
|
||||||
input logic[N-1:0] addr,
|
output logic [N-1:0] instr
|
||||||
output logic[N-1:0] instr
|
|
||||||
);
|
);
|
||||||
logic[BYTE_WIDTH-1:0] mem [N_INSTR*BYTE_WIDTH-1:0];
|
logic [BYTE_WIDTH-1:0] mem[N_INSTR*BYTE_WIDTH-1:0];
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
instr = {mem[addr + 'd0],
|
instr = {mem[addr+'d0], mem[addr+'d1], mem[addr+'d2], mem[addr+'d3]};
|
||||||
mem[addr + 'd1],
|
end
|
||||||
mem[addr + 'd2],
|
|
||||||
mem[addr + 'd3]};
|
|
||||||
end
|
|
||||||
|
|
||||||
initial $readmemh("sandbox.mem", mem);
|
initial $readmemh("sandbox.mem", mem);
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
module JumpControl(
|
module JumpControl (
|
||||||
input logic jump, branch, branch_alu_neg, zero,
|
input logic jump,
|
||||||
|
branch,
|
||||||
|
branch_alu_neg,
|
||||||
|
zero,
|
||||||
output logic pc_src
|
output logic pc_src
|
||||||
);
|
);
|
||||||
logic alu_result, branch_result;
|
logic alu_result, branch_result;
|
||||||
assign alu_result = !zero;
|
assign alu_result = !zero;
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case(branch_alu_neg)
|
case (branch_alu_neg)
|
||||||
'd0: branch_result = alu_result;
|
'd0: branch_result = alu_result;
|
||||||
'd1: branch_result = !alu_result;
|
'd1: branch_result = !alu_result;
|
||||||
endcase
|
default: branch_result = 'dx;
|
||||||
end
|
endcase
|
||||||
|
end
|
||||||
assign pc_src = (branch & branch_result) | jump;
|
|
||||||
|
assign pc_src = (branch & branch_result) | jump;
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,47 +1,46 @@
|
|||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
module PipelinedControlUnit
|
module PipelinedControlUnit (
|
||||||
(
|
input logic [6:0] opcode,
|
||||||
input logic[6:0] opcode,
|
input logic [2:0] funct_3,
|
||||||
input logic[2:0] funct_3,
|
input logic [6:0] funct_7,
|
||||||
input logic[6:0] funct_7,
|
|
||||||
output logic reg_write,
|
output logic reg_write,
|
||||||
output logic[1:0] result_src,
|
output logic [1:0] result_src,
|
||||||
output logic mem_write,
|
output logic mem_write,
|
||||||
output logic branch,
|
output logic branch,
|
||||||
output logic[2:0] alu_ctrl,
|
output logic [2:0] alu_ctrl,
|
||||||
output logic alu_src,
|
output logic alu_src,
|
||||||
output logic[1:0] imm_src
|
output logic [1:0] imm_src
|
||||||
);
|
);
|
||||||
//logic branch, branch_result, branch_neg, jump;
|
//logic branch, branch_result, branch_neg, jump;
|
||||||
//assign pc_src = (branch & branch_result) | jump;
|
//assign pc_src = (branch & branch_result) | jump;
|
||||||
/*
|
/*
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case(branch_neg)
|
case(branch_neg)
|
||||||
'd0: branch_result = !zero;
|
'd0: branch_result = !zero;
|
||||||
'd1: branch_result = zero;
|
'd1: branch_result = zero;
|
||||||
endcase
|
endcase
|
||||||
end*/
|
end*/
|
||||||
|
|
||||||
logic[1:0] alu_op;
|
logic [1:0] alu_op;
|
||||||
MainDecoder main_decoder(
|
MainDecoder main_decoder (
|
||||||
opcode,
|
opcode,
|
||||||
branch,
|
branch,
|
||||||
jump,
|
jump,
|
||||||
result_src,
|
result_src,
|
||||||
mem_write,
|
mem_write,
|
||||||
alu_src,
|
alu_src,
|
||||||
imm_src,
|
imm_src,
|
||||||
reg_write,
|
reg_write,
|
||||||
alu_op
|
alu_op
|
||||||
);
|
);
|
||||||
|
|
||||||
ALUDecoder alu_decoder(
|
ALUDecoder alu_decoder (
|
||||||
opcode[5],
|
opcode[5],
|
||||||
funct_3,
|
funct_3,
|
||||||
funct_7[5],
|
funct_7[5],
|
||||||
alu_op,
|
alu_op,
|
||||||
alu_ctrl,
|
alu_ctrl,
|
||||||
branch_neg
|
branch_neg
|
||||||
);
|
);
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -2,21 +2,18 @@
|
|||||||
|
|
||||||
// 2**N to N Priority encoder
|
// 2**N to N Priority encoder
|
||||||
module PriorityEncoder #(
|
module PriorityEncoder #(
|
||||||
parameter N = 4
|
parameter int N = 4
|
||||||
)(
|
) (
|
||||||
input logic[2**N - 1:0] data_in,
|
input logic [2**N - 1:0] data_in,
|
||||||
output logic[N - 1:0] data_out,
|
output logic [N - 1:0] data_out,
|
||||||
output logic valid
|
output logic valid
|
||||||
);
|
);
|
||||||
always_comb begin
|
always_comb begin
|
||||||
data_out = 'dx;
|
data_out = 'dx;
|
||||||
for (int i = 0; i < 2**N; i++) begin
|
for (int i = 0; i < 2 ** N; i++) begin
|
||||||
if (data_in[i])
|
if (data_in[i]) data_out = i;
|
||||||
data_out = i;
|
|
||||||
end
|
end
|
||||||
if (data_in == 0)
|
if (data_in == 0) valid = 0;
|
||||||
valid = 0;
|
else valid = 1;
|
||||||
else
|
end
|
||||||
valid = 1;
|
|
||||||
end
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -2,38 +2,37 @@
|
|||||||
|
|
||||||
// N = Bit width
|
// N = Bit width
|
||||||
module RegisterFile #(
|
module RegisterFile #(
|
||||||
parameter N_REG_ADDR = 5,
|
parameter int N_REG_ADDR = 5,
|
||||||
parameter N_REG = 32,
|
parameter int N_REG = 32,
|
||||||
parameter N_DATA = 32
|
parameter int N_DATA = 32
|
||||||
) (
|
) (
|
||||||
input logic clk, rst,
|
input logic clk,
|
||||||
input logic[N_REG_ADDR-1:0] addr_1, addr_2, addr_3,
|
rst,
|
||||||
|
input logic [N_REG_ADDR-1:0] addr_1,
|
||||||
|
addr_2,
|
||||||
|
addr_3,
|
||||||
input logic write_enable_3,
|
input logic write_enable_3,
|
||||||
input logic[N_DATA-1:0] write_data_3,
|
input logic [N_DATA-1:0] write_data_3,
|
||||||
output logic[N_DATA-1:0] read_data_1, read_data_2
|
output logic [N_DATA-1:0] read_data_1,
|
||||||
);
|
read_data_2
|
||||||
logic[N_DATA-1:0] mem[N_REG-1:1];
|
);
|
||||||
logic[N_DATA-1:0] zero;
|
logic [N_DATA-1:0] mem [N_REG-1:1];
|
||||||
|
logic [N_DATA-1:0] zero;
|
||||||
always_comb begin
|
|
||||||
zero = 'd0;
|
always_comb begin
|
||||||
if (addr_1 == 'd0)
|
zero = 'd0;
|
||||||
read_data_1 = zero;
|
if (addr_1 == 'd0) read_data_1 = zero;
|
||||||
else
|
else read_data_1 = mem[addr_1];
|
||||||
read_data_1 = mem[addr_1];
|
if (addr_2 == 'd0) read_data_2 = zero;
|
||||||
if (addr_2 == 'd0)
|
else read_data_2 = mem[addr_2];
|
||||||
read_data_2 = zero;
|
end
|
||||||
else
|
|
||||||
read_data_2 = mem[addr_2];
|
always_ff @(posedge clk) begin
|
||||||
end
|
if (rst) begin
|
||||||
|
mem <= '{default: '0};
|
||||||
always_ff @(posedge clk) begin
|
mem[2] <= 'd255;
|
||||||
if (rst) begin
|
end else if (write_enable_3) begin
|
||||||
mem <= '{default: '0};
|
mem[addr_3] <= write_data_3;
|
||||||
mem[2] <= 'd255;
|
|
||||||
end
|
|
||||||
else if (write_enable_3) begin
|
|
||||||
mem[addr_3] <= write_data_3;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
Reference in New Issue
Block a user