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
|
||||
// N = Bit width
|
||||
module ALU #(parameter N = 32)
|
||||
(
|
||||
input logic[N-1:0] a,
|
||||
input logic[N-1:0] b,
|
||||
input logic[2:0] opcode,
|
||||
output logic[N-1:0] result,
|
||||
output logic[3:0] status
|
||||
module ALU #(
|
||||
parameter integer N = 32
|
||||
) (
|
||||
input logic [N-1:0] a,
|
||||
input logic [N-1:0] b,
|
||||
input logic [ 2:0] opcode,
|
||||
output logic [N-1:0] result,
|
||||
output logic [ 3:0] status
|
||||
);
|
||||
logic n, z, c, v;
|
||||
logic opsign_comp, v_value;
|
||||
always_comb begin
|
||||
// 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]));
|
||||
// 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
|
||||
v_value = opsign_comp && (result != a[N-1]);
|
||||
case(opcode)
|
||||
'b000: begin // Addition
|
||||
{c, result} = a + b;
|
||||
v = v_value;
|
||||
end
|
||||
'b001: begin // Substraction
|
||||
{c, result} = a - b;
|
||||
v = v_value;
|
||||
end
|
||||
'b011: begin // Or
|
||||
result = a | b;
|
||||
c = 'b0;
|
||||
v = 'b0;
|
||||
end
|
||||
'b010: begin // And
|
||||
result = a & b;
|
||||
c = 'b0;
|
||||
v = 'b0;
|
||||
end
|
||||
'b101: begin // Set less than
|
||||
result = a < b;
|
||||
c = 'b0;
|
||||
v = 'b0;
|
||||
end
|
||||
default: begin
|
||||
result = 'dx;
|
||||
c = 'dx;
|
||||
v = 'dx;
|
||||
end
|
||||
endcase
|
||||
n = result[N-1];
|
||||
z = (result == '0);
|
||||
status = {n, z, c, v};
|
||||
end
|
||||
endmodule
|
||||
logic n, z, c, v;
|
||||
logic opsign_comp, v_value;
|
||||
always_comb begin
|
||||
// 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]));
|
||||
// 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
|
||||
v_value = opsign_comp && (result != a[N-1]);
|
||||
case (opcode)
|
||||
'b000: begin // Addition
|
||||
{c, result} = a + b;
|
||||
v = v_value;
|
||||
end
|
||||
'b001: begin // Substraction
|
||||
{c, result} = a - b;
|
||||
v = v_value;
|
||||
end
|
||||
'b011: begin // Or
|
||||
result = a | b;
|
||||
c = 'b0;
|
||||
v = 'b0;
|
||||
end
|
||||
'b010: begin // And
|
||||
result = a & b;
|
||||
c = 'b0;
|
||||
v = 'b0;
|
||||
end
|
||||
'b101: begin // Set less than
|
||||
result = a < b;
|
||||
c = 'b0;
|
||||
v = 'b0;
|
||||
end
|
||||
default: begin
|
||||
result = 'dx;
|
||||
c = 'dx;
|
||||
v = 'dx;
|
||||
end
|
||||
endcase
|
||||
n = result[N-1];
|
||||
z = (result == '0);
|
||||
status = {n, z, c, v};
|
||||
end
|
||||
endmodule
|
||||
|
@ -1,63 +1,65 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module ALUDecoder(
|
||||
module ALUDecoder (
|
||||
input logic opcode_5,
|
||||
input logic[2:0] funct_3,
|
||||
input logic [2:0] funct_3,
|
||||
input logic funct_7_5,
|
||||
input logic[1:0] alu_op,
|
||||
output logic[2:0] alu_ctrl,
|
||||
input logic [1:0] alu_op,
|
||||
output logic [2:0] alu_ctrl,
|
||||
output logic branch_neg
|
||||
);
|
||||
always_comb begin
|
||||
casex({alu_op, funct_3, opcode_5, funct_7_5})
|
||||
'b00xxxxx: begin
|
||||
alu_ctrl = 'b000; // lw sw
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b01000xx: begin
|
||||
alu_ctrl = 'b001; // beq
|
||||
branch_neg = 1;
|
||||
end
|
||||
'b01100xx: begin
|
||||
alu_ctrl = 'b101; // blt
|
||||
branch_neg = 0;
|
||||
end
|
||||
'b01101xx: begin
|
||||
alu_ctrl = 'b101; // bge
|
||||
branch_neg = 1;
|
||||
end
|
||||
'b1000000: begin
|
||||
alu_ctrl = 'b000; // add
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b1000001: begin
|
||||
alu_ctrl = 'b000; // add
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b1000010: begin
|
||||
alu_ctrl = 'b000; // add
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b1000011: begin
|
||||
alu_ctrl = 'b001; // sub
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b10010xx: begin
|
||||
alu_ctrl = 'b101; // slt
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b10110xx: begin
|
||||
alu_ctrl = 'b000; // or
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b10111xx: begin
|
||||
alu_ctrl = 'b000; // and
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
default: begin
|
||||
alu_ctrl = 'dx;
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
always_comb begin
|
||||
casex ({
|
||||
alu_op, funct_3, opcode_5, funct_7_5
|
||||
})
|
||||
'b00xxxxx: begin
|
||||
alu_ctrl = 'b000; // lw sw
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b01000xx: begin
|
||||
alu_ctrl = 'b001; // beq
|
||||
branch_neg = 1;
|
||||
end
|
||||
'b01100xx: begin
|
||||
alu_ctrl = 'b101; // blt
|
||||
branch_neg = 0;
|
||||
end
|
||||
'b01101xx: begin
|
||||
alu_ctrl = 'b101; // bge
|
||||
branch_neg = 1;
|
||||
end
|
||||
'b1000000: begin
|
||||
alu_ctrl = 'b000; // add
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b1000001: begin
|
||||
alu_ctrl = 'b000; // add
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b1000010: begin
|
||||
alu_ctrl = 'b000; // add
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b1000011: begin
|
||||
alu_ctrl = 'b001; // sub
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b10010xx: begin
|
||||
alu_ctrl = 'b101; // slt
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b10110xx: begin
|
||||
alu_ctrl = 'b000; // or
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
'b10111xx: begin
|
||||
alu_ctrl = 'b000; // and
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
default: begin
|
||||
alu_ctrl = 'dx;
|
||||
branch_neg = 'dx;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
|
@ -1,88 +1,92 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module CacheController #(
|
||||
parameter ADDR_SIZE = 32,
|
||||
parameter NUM_SETS = 16,
|
||||
parameter NUM_WAYS = 4,
|
||||
parameter BLOCK_SIZE = 32
|
||||
parameter int ADDR_SIZE = 32,
|
||||
parameter int NUM_SETS = 16,
|
||||
parameter int NUM_WAYS = 4,
|
||||
parameter int BLOCK_SIZE = 32
|
||||
) (
|
||||
input logic clk,
|
||||
input logic[ADDR_SIZE - 1:0] addr,
|
||||
input logic [ADDR_SIZE - 1:0] addr,
|
||||
input logic write_enable,
|
||||
input logic replace_way,
|
||||
input logic[NUM_WAYS - 1:0] hits,
|
||||
input logic[NUM_WAYS - 1:0] valid_flags,
|
||||
output logic[SET_SIZE - 1:0] set,
|
||||
output logic[TAG_SIZE - 1:0] tag,
|
||||
output logic[WAY_SIZE - 1:0] way,
|
||||
input logic [NUM_WAYS - 1:0] hits,
|
||||
input logic [NUM_WAYS - 1:0] valid_flags,
|
||||
output logic [SetSize - 1:0] set,
|
||||
output logic [TagSize - 1:0] tag,
|
||||
output logic [WaySize - 1:0] way,
|
||||
output logic hit,
|
||||
output logic cru_enable
|
||||
);
|
||||
localparam NUM_BLOCK_BYTES = BLOCK_SIZE / 4;
|
||||
localparam BYTE_OFFSET_SIZE = $clog2(NUM_BLOCK_BYTES);
|
||||
localparam SET_SIZE = $clog2(NUM_SETS);
|
||||
localparam TAG_SIZE = ADDR_SIZE - SET_SIZE - BYTE_OFFSET_SIZE;
|
||||
localparam WAY_SIZE = $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);
|
||||
localparam int NumBlockBytes = BLOCK_SIZE / 4;
|
||||
localparam int ByteOffsetSize = $clog2(NumBlockBytes);
|
||||
localparam int SetSize = $clog2(NUM_SETS);
|
||||
localparam int TagSize = ADDR_SIZE - SetSize - ByteOffsetSize;
|
||||
localparam int WaySize = $clog2(NUM_WAYS);
|
||||
|
||||
logic valid;
|
||||
always_comb begin
|
||||
packed_addr = cache_addr'(addr);
|
||||
set = packed_addr.set;
|
||||
tag = packed_addr.tag;
|
||||
|
||||
hit = |hits;
|
||||
valid = &valid_flags;
|
||||
typedef struct packed {
|
||||
logic [ByteOffsetSize - 1:0] byte_offset;
|
||||
logic [SetSize - 1:0] set;
|
||||
logic [TagSize - 1:0] tag;
|
||||
} cache_addr_t;
|
||||
|
||||
state = cache_state'{write_enable, valid};
|
||||
typedef enum logic [1:0] {
|
||||
READ = 'b00,
|
||||
WRITE_UNVALID = 'b10,
|
||||
REPLACE = 'b11
|
||||
} cache_state_t;
|
||||
|
||||
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
|
||||
/*
|
||||
always_ff @(posedge clk) begin
|
||||
cache_addr packed_addr;
|
||||
cache_state_t state;
|
||||
|
||||
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
|
||||
|
@ -1,58 +1,59 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module CacheMemory #(
|
||||
parameter ADDR_SIZE = 32,
|
||||
parameter NUM_SETS = 16,
|
||||
parameter NUM_WAYS = 4,
|
||||
parameter BLOCK_SIZE = 32
|
||||
)(
|
||||
input logic clk, rst,
|
||||
input logic[WAY_SIZE - 1:0] way,
|
||||
input logic[SET_SIZE - 1:0] set,
|
||||
input logic[TAG_SIZE - 1:0] tag,
|
||||
parameter int ADDR_SIZE = 32,
|
||||
parameter int NUM_SETS = 16,
|
||||
parameter int NUM_WAYS = 4,
|
||||
parameter int BLOCK_SIZE = 32
|
||||
) (
|
||||
input logic clk,
|
||||
rst,
|
||||
input logic [WaySize - 1:0] way,
|
||||
input logic [SetSize - 1:0] set,
|
||||
input logic [TagSize - 1:0] tag,
|
||||
input logic write_enable,
|
||||
input logic[BLOCK_SIZE - 1:0] write_data,
|
||||
output logic[BLOCK_SIZE - 1:0] read_data,
|
||||
output logic[NUM_WAYS - 1:0] hits,
|
||||
output logic[NUM_WAYS - 1:0] valid_flags
|
||||
input logic [BLOCK_SIZE - 1:0] write_data,
|
||||
output logic [BLOCK_SIZE - 1:0] read_data,
|
||||
output logic [NUM_WAYS - 1:0] hits,
|
||||
output logic [NUM_WAYS - 1:0] valid_flags
|
||||
);
|
||||
localparam NUM_BLOCK_BYTES = BLOCK_SIZE / 4;
|
||||
localparam BYTE_OFFSET_SIZE = $clog2(NUM_BLOCK_BYTES);
|
||||
localparam WAY_SIZE = $clog2(NUM_WAYS);
|
||||
localparam SET_SIZE = $clog2(NUM_SETS);
|
||||
localparam TAG_SIZE = ADDR_SIZE - SET_SIZE - BYTE_OFFSET_SIZE;
|
||||
|
||||
typedef struct packed {
|
||||
logic[BLOCK_SIZE - 1:0] data;
|
||||
logic[TAG_SIZE - 1:0] tag;
|
||||
logic valid;
|
||||
} cache_line;
|
||||
|
||||
typedef cache_line[NUM_SETS - 1:0] cache_way;
|
||||
cache_way[NUM_WAYS - 1:0] ways;
|
||||
|
||||
assign read_data = ways[way][set].data;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
// Reset valid flags
|
||||
for (int i = 0; i < NUM_WAYS; i++) begin
|
||||
for (int j = 0; j < NUM_SETS; j++) begin
|
||||
ways[i][j].data <= 'dx;
|
||||
ways[i][j].tag <= 'dx;
|
||||
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);
|
||||
localparam int NumBlockBytes = BLOCK_SIZE / 4;
|
||||
localparam int ByteOffsetSize = $clog2(NumBlockBytes);
|
||||
localparam int WaySize = $clog2(NUM_WAYS);
|
||||
localparam int SetSize = $clog2(NUM_SETS);
|
||||
localparam int TagSize = ADDR_SIZE - SetSize - ByteOffsetSize;
|
||||
|
||||
typedef struct packed {
|
||||
logic [BLOCK_SIZE - 1:0] data;
|
||||
logic [TagSize - 1:0] tag;
|
||||
logic valid;
|
||||
} cache_line_t;
|
||||
|
||||
typedef cache_line [NUM_SETS - 1:0] cache_way;
|
||||
cache_way [NUM_WAYS - 1:0] ways;
|
||||
|
||||
assign read_data = ways[way][set].data;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
// Reset valid flags
|
||||
for (int i = 0; i < NUM_WAYS; i++) begin
|
||||
for (int j = 0; j < NUM_SETS; j++) begin
|
||||
ways[i][j].data <= 'dx;
|
||||
ways[i][j].tag <= 'dx;
|
||||
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
|
||||
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::*;
|
||||
|
||||
module ControlUnit
|
||||
(
|
||||
input logic[6:0] opcode,
|
||||
input logic[2:0] funct_3,
|
||||
input logic[6:0] funct_7,
|
||||
output logic[1:0] result_src,
|
||||
module ControlUnit (
|
||||
input logic [6:0] opcode,
|
||||
input logic [2:0] funct_3,
|
||||
input logic [6:0] funct_7,
|
||||
output logic [1:0] result_src,
|
||||
output logic mem_write,
|
||||
output logic[2:0] alu_ctrl,
|
||||
output logic [2:0] alu_ctrl,
|
||||
output logic alu_src,
|
||||
output logic[1:0] imm_src,
|
||||
output logic [1:0] imm_src,
|
||||
output logic reg_write,
|
||||
output logic jump,
|
||||
output logic branch, branch_alu_neg
|
||||
output logic branch,
|
||||
branch_alu_neg
|
||||
);
|
||||
logic[1:0] alu_op;
|
||||
MainDecoder main_decoder(
|
||||
opcode,
|
||||
branch,
|
||||
jump,
|
||||
result_src,
|
||||
mem_write,
|
||||
alu_src,
|
||||
imm_src,
|
||||
reg_write,
|
||||
alu_op
|
||||
);
|
||||
|
||||
ALUDecoder alu_decoder(
|
||||
opcode[5],
|
||||
funct_3,
|
||||
funct_7[5],
|
||||
alu_op,
|
||||
alu_ctrl,
|
||||
branch_alu_neg
|
||||
);
|
||||
logic [1:0] alu_op;
|
||||
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 (
|
||||
.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_alu_neg)
|
||||
);
|
||||
endmodule
|
||||
|
@ -1,17 +1,17 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module Extend
|
||||
(
|
||||
input logic[1:0] imm_src,
|
||||
input logic[31:7] instr,
|
||||
output logic[31:0] imm_ext
|
||||
module Extend (
|
||||
input logic [ 1:0] imm_src,
|
||||
input logic [31:7] instr,
|
||||
output logic [31:0] imm_ext
|
||||
);
|
||||
always_comb begin
|
||||
case(imm_src)
|
||||
'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
|
||||
'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
|
||||
endcase
|
||||
end
|
||||
always_comb begin
|
||||
case (imm_src)
|
||||
'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
|
||||
'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
|
||||
default: imm_ext = 'dx;
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
|
@ -2,45 +2,52 @@
|
||||
|
||||
module HazardUnit (
|
||||
input logic rst,
|
||||
execute_pc_src, execute_result_src_0,
|
||||
memory_reg_write, writeback_reg_write,
|
||||
input logic[4:0] decode_rs_1, decode_rs_2,
|
||||
execute_rs_1, 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
|
||||
execute_pc_src,
|
||||
execute_result_src_0,
|
||||
memory_reg_write,
|
||||
writeback_reg_write,
|
||||
input logic [4:0] decode_rs_1,
|
||||
decode_rs_2,
|
||||
execute_rs_1,
|
||||
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;
|
||||
always_comb begin
|
||||
if (rst) begin
|
||||
fetch_stall = 0;
|
||||
decode_stall = 0;
|
||||
decode_flush = 1;
|
||||
execute_flush = 1;
|
||||
execute_forward_a = 0;
|
||||
execute_forward_b = 0;
|
||||
end else begin
|
||||
if (((execute_rs_1 == memory_rd) & memory_reg_write) & (execute_rs_1 != 0))
|
||||
execute_forward_a = 'b10;
|
||||
else if (((execute_rs_1 == writeback_rd) & writeback_reg_write) & (execute_rs_1 != 0))
|
||||
execute_forward_a = 'b01;
|
||||
else
|
||||
execute_forward_a = 'b00;
|
||||
|
||||
if (((execute_rs_2 == memory_rd) & memory_reg_write) & (execute_rs_2 != 0))
|
||||
execute_forward_b = 'b10;
|
||||
else if (((execute_rs_2 == writeback_rd) & writeback_reg_write) & (execute_rs_2 != 0))
|
||||
execute_forward_b = 'b01;
|
||||
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;
|
||||
decode_stall = lw_stall;
|
||||
|
||||
decode_flush = execute_pc_src;
|
||||
execute_flush = lw_stall | execute_pc_src;
|
||||
end
|
||||
logic lw_stall;
|
||||
always_comb begin
|
||||
if (rst) begin
|
||||
fetch_stall = 0;
|
||||
decode_stall = 0;
|
||||
decode_flush = 1;
|
||||
execute_flush = 1;
|
||||
execute_forward_a = 0;
|
||||
execute_forward_b = 0;
|
||||
end else begin
|
||||
if (((execute_rs_1 == memory_rd) & memory_reg_write) & (execute_rs_1 != 0))
|
||||
execute_forward_a = 'b10;
|
||||
else if (((execute_rs_1 == writeback_rd) & writeback_reg_write) & (execute_rs_1 != 0))
|
||||
execute_forward_a = 'b01;
|
||||
else execute_forward_a = 'b00;
|
||||
|
||||
if (((execute_rs_2 == memory_rd) & memory_reg_write) & (execute_rs_2 != 0))
|
||||
execute_forward_b = 'b10;
|
||||
else if (((execute_rs_2 == writeback_rd) & writeback_reg_write) & (execute_rs_2 != 0))
|
||||
execute_forward_b = 'b01;
|
||||
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;
|
||||
decode_stall = lw_stall;
|
||||
|
||||
decode_flush = execute_pc_src;
|
||||
execute_flush = lw_stall | execute_pc_src;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
@ -2,22 +2,18 @@
|
||||
|
||||
// N = Bit width
|
||||
module InstructionMemory #(
|
||||
parameter N = 32,
|
||||
parameter N_INSTR = 32,
|
||||
parameter BYTE_WIDTH = 8
|
||||
)
|
||||
(
|
||||
input logic[N-1:0] addr,
|
||||
output logic[N-1:0] instr
|
||||
parameter int N = 32,
|
||||
parameter int N_INSTR = 32,
|
||||
parameter int BYTE_WIDTH = 8
|
||||
) (
|
||||
input logic [N-1:0] addr,
|
||||
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
|
||||
instr = {mem[addr + 'd0],
|
||||
mem[addr + 'd1],
|
||||
mem[addr + 'd2],
|
||||
mem[addr + 'd3]};
|
||||
end
|
||||
always_comb begin
|
||||
instr = {mem[addr+'d0], mem[addr+'d1], mem[addr+'d2], mem[addr+'d3]};
|
||||
end
|
||||
|
||||
initial $readmemh("sandbox.mem", mem);
|
||||
initial $readmemh("sandbox.mem", mem);
|
||||
endmodule
|
||||
|
@ -1,18 +1,22 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module JumpControl(
|
||||
input logic jump, branch, branch_alu_neg, zero,
|
||||
module JumpControl (
|
||||
input logic jump,
|
||||
branch,
|
||||
branch_alu_neg,
|
||||
zero,
|
||||
output logic pc_src
|
||||
);
|
||||
logic alu_result, branch_result;
|
||||
assign alu_result = !zero;
|
||||
logic alu_result, branch_result;
|
||||
assign alu_result = !zero;
|
||||
|
||||
always_comb begin
|
||||
case(branch_alu_neg)
|
||||
'd0: branch_result = alu_result;
|
||||
'd1: branch_result = !alu_result;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign pc_src = (branch & branch_result) | jump;
|
||||
always_comb begin
|
||||
case (branch_alu_neg)
|
||||
'd0: branch_result = alu_result;
|
||||
'd1: branch_result = !alu_result;
|
||||
default: branch_result = 'dx;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign pc_src = (branch & branch_result) | jump;
|
||||
endmodule
|
||||
|
@ -1,47 +1,46 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module PipelinedControlUnit
|
||||
(
|
||||
input logic[6:0] opcode,
|
||||
input logic[2:0] funct_3,
|
||||
input logic[6:0] funct_7,
|
||||
module PipelinedControlUnit (
|
||||
input logic [6:0] opcode,
|
||||
input logic [2:0] funct_3,
|
||||
input logic [6:0] funct_7,
|
||||
output logic reg_write,
|
||||
output logic[1:0] result_src,
|
||||
output logic [1:0] result_src,
|
||||
output logic mem_write,
|
||||
output logic branch,
|
||||
output logic[2:0] alu_ctrl,
|
||||
output logic [2:0] alu_ctrl,
|
||||
output logic alu_src,
|
||||
output logic[1:0] imm_src
|
||||
output logic [1:0] imm_src
|
||||
);
|
||||
//logic branch, branch_result, branch_neg, jump;
|
||||
//assign pc_src = (branch & branch_result) | jump;
|
||||
/*
|
||||
//logic branch, branch_result, branch_neg, jump;
|
||||
//assign pc_src = (branch & branch_result) | jump;
|
||||
/*
|
||||
always_comb begin
|
||||
case(branch_neg)
|
||||
'd0: branch_result = !zero;
|
||||
'd1: branch_result = zero;
|
||||
endcase
|
||||
end*/
|
||||
|
||||
logic[1:0] alu_op;
|
||||
MainDecoder main_decoder(
|
||||
opcode,
|
||||
branch,
|
||||
jump,
|
||||
result_src,
|
||||
mem_write,
|
||||
alu_src,
|
||||
imm_src,
|
||||
reg_write,
|
||||
alu_op
|
||||
);
|
||||
|
||||
ALUDecoder alu_decoder(
|
||||
opcode[5],
|
||||
funct_3,
|
||||
funct_7[5],
|
||||
alu_op,
|
||||
alu_ctrl,
|
||||
branch_neg
|
||||
);
|
||||
|
||||
logic [1:0] alu_op;
|
||||
MainDecoder main_decoder (
|
||||
opcode,
|
||||
branch,
|
||||
jump,
|
||||
result_src,
|
||||
mem_write,
|
||||
alu_src,
|
||||
imm_src,
|
||||
reg_write,
|
||||
alu_op
|
||||
);
|
||||
|
||||
ALUDecoder alu_decoder (
|
||||
opcode[5],
|
||||
funct_3,
|
||||
funct_7[5],
|
||||
alu_op,
|
||||
alu_ctrl,
|
||||
branch_neg
|
||||
);
|
||||
endmodule
|
||||
|
@ -2,21 +2,18 @@
|
||||
|
||||
// 2**N to N Priority encoder
|
||||
module PriorityEncoder #(
|
||||
parameter N = 4
|
||||
)(
|
||||
input logic[2**N - 1:0] data_in,
|
||||
output logic[N - 1:0] data_out,
|
||||
parameter int N = 4
|
||||
) (
|
||||
input logic [2**N - 1:0] data_in,
|
||||
output logic [N - 1:0] data_out,
|
||||
output logic valid
|
||||
);
|
||||
always_comb begin
|
||||
always_comb begin
|
||||
data_out = 'dx;
|
||||
for (int i = 0; i < 2**N; i++) begin
|
||||
if (data_in[i])
|
||||
data_out = i;
|
||||
for (int i = 0; i < 2 ** N; i++) begin
|
||||
if (data_in[i]) data_out = i;
|
||||
end
|
||||
if (data_in == 0)
|
||||
valid = 0;
|
||||
else
|
||||
valid = 1;
|
||||
end
|
||||
if (data_in == 0) valid = 0;
|
||||
else valid = 1;
|
||||
end
|
||||
endmodule
|
||||
|
@ -2,38 +2,37 @@
|
||||
|
||||
// N = Bit width
|
||||
module RegisterFile #(
|
||||
parameter N_REG_ADDR = 5,
|
||||
parameter N_REG = 32,
|
||||
parameter N_DATA = 32
|
||||
parameter int N_REG_ADDR = 5,
|
||||
parameter int N_REG = 32,
|
||||
parameter int N_DATA = 32
|
||||
) (
|
||||
input logic clk, rst,
|
||||
input logic[N_REG_ADDR-1:0] addr_1, addr_2, addr_3,
|
||||
input logic clk,
|
||||
rst,
|
||||
input logic [N_REG_ADDR-1:0] addr_1,
|
||||
addr_2,
|
||||
addr_3,
|
||||
input logic write_enable_3,
|
||||
input logic[N_DATA-1:0] write_data_3,
|
||||
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;
|
||||
|
||||
always_comb begin
|
||||
zero = 'd0;
|
||||
if (addr_1 == 'd0)
|
||||
read_data_1 = zero;
|
||||
else
|
||||
read_data_1 = mem[addr_1];
|
||||
if (addr_2 == 'd0)
|
||||
read_data_2 = zero;
|
||||
else
|
||||
read_data_2 = mem[addr_2];
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
mem <= '{default: '0};
|
||||
mem[2] <= 'd255;
|
||||
end
|
||||
else if (write_enable_3) begin
|
||||
mem[addr_3] <= write_data_3;
|
||||
end
|
||||
input logic [N_DATA-1:0] write_data_3,
|
||||
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;
|
||||
|
||||
always_comb begin
|
||||
zero = 'd0;
|
||||
if (addr_1 == 'd0) read_data_1 = zero;
|
||||
else read_data_1 = mem[addr_1];
|
||||
if (addr_2 == 'd0) read_data_2 = zero;
|
||||
else read_data_2 = mem[addr_2];
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
mem <= '{default: '0};
|
||||
mem[2] <= 'd255;
|
||||
end else if (write_enable_3) begin
|
||||
mem[addr_3] <= write_data_3;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue
Block a user