Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ vsim.
*.summary
*.tcl
*.txt # Explicitly add any text files used
*.bin
*~
*example*
*sopc_*
Expand Down
10 changes: 6 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
DIR := ./xpacks/.bin
SRC_DIR := ./tests/src
HEX_DIR := ./tests/hex
BIN_DIR := ./tests/bin
OBJ_DIR := ./tests/obj

CC := $(DIR)/riscv-none-elf-gcc
Expand All @@ -9,7 +10,7 @@ OBJDUMP := $(DIR)/riscv-none-elf-objdump
OBJCOPY := $(DIR)/riscv-none-elf-objcopy
MEM_WORD_LENGTH := 4

CFLAGS := -O0 -ffunction-sections -Xlinker -g -T./tests/risc.ld -mbig-endian -nostdlib -ffreestanding -fno-pie -fno-stack-protector -Wall -mno-fdiv -march=rv32i -mabi=ilp32
CFLAGS := -O0 -ffunction-sections -Xlinker -g -T./tests/risc.ld -msmall-data-limit=0 -mlittle-endian -nostdlib -ffreestanding -fno-pie -fno-stack-protector -Wall -mno-fdiv -march=rv32i -mabi=ilp32

SRCS = $(wildcard $(SRC_DIR)/*.c)

Expand All @@ -19,10 +20,11 @@ PROGS = $(patsubst ${SRC_DIR}/%.c,%,$(SRCS))
all: $(PROGS)

$(PROGS):
mkdir -p $(HEX_DIR) $(BIN_DIR) $(OBJ_DIR)
$(CC) $(CFLAGS) -o $(OBJ_DIR)/[email protected] $(SRC_DIR)/[email protected]
$(OBJCOPY) --remove-section=.comment --reverse-bytes=$(MEM_WORD_LENGTH) \
--verilog-data-width $(MEM_WORD_LENGTH) \
$(OBJ_DIR)/[email protected] -O verilog $(HEX_DIR)/[email protected]
$(OBJCOPY) --remove-section=.comment \
$(OBJ_DIR)/[email protected] -O binary $(BIN_DIR)/[email protected]
$(PYTHON) ./tests/freedom-bin2hex.py --bit-width=32 $(BIN_DIR)/[email protected] $(HEX_DIR)/[email protected]

test:
python3 -m pytest ./tests
Expand Down
6 changes: 6 additions & 0 deletions src/de10_peripherals.sv
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ module de10_peripherals(
reg_dflop gpio1 [31:0] (.q(qn[0]), .d(idata), .we(we[0]), .clk(clk), .rst(rst));
reg_dflop gpio2 [31:0] (.q(qn[1]), .d(idata), .we(we[1]), .clk(clk), .rst(rst));

wire [31:0] gpio1_debug;
wire [31:0] gpio2_debug;

assign gpio1_debug = qn[0];
assign gpio2_debug = qn[1];

always @ (*) begin
case({periph_addr})
22'd0: begin
Expand Down
13 changes: 7 additions & 6 deletions src/fetch.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ module fetch (
input en_jmp, // Signal that enables jumps
input [31:0] imm, // The immediate value from the instruction
input stall, // Signal for a full pipeline a stall is occuring
input imem_stall, // Signal for specifcally a stall due to instruction cache
input first_stage_stall, // Signal for which the first stage is stalling
input pc_stall, // Signal for specifcally a stall due to instruction cache
input clk, // Clock
input rst); // Reset

Expand All @@ -27,31 +28,31 @@ module fetch (
reg [31:0] next_addr;

// Program Counter
pipeline_latch pc [31:0] (.q(curr_addr), .d(next_addr), .stall(stall | imem_stall), .clk(clk), .rst(rst));
pipeline_latch pc [31:0] (.q(curr_addr), .d(next_addr), .stall(stall | pc_stall | first_stage_stall), .clk(clk), .rst(rst));

// Instruction Latch
pipeline_latch instr_latch [31:0] (.q(oinstr), .d(iinstr), .stall(stall), .clk(clk), .rst(rst));
pipeline_latch instr_latch [31:0] (.q(oinstr), .d(iinstr), .stall(stall | first_stage_stall), .clk(clk), .rst(rst));

// Latch for the current address plus four bytes
wire [31:0] curr_addr_step_conn_latch1;
wire [31:0] curr_addr_step_conn_latch2;
wire [31:0] curr_addr_step_conn_latch3;
pipeline_latch curr_addr_step_latch1 [31:0] (.q(curr_addr_step_conn_latch1), .d(curr_addr_step), .stall(stall), .clk(clk), .rst(rst));
pipeline_latch curr_addr_step_latch1 [31:0] (.q(curr_addr_step_conn_latch1), .d(curr_addr_step), .stall(stall | first_stage_stall), .clk(clk), .rst(rst));
pipeline_latch curr_addr_step_latch2 [31:0] (.q(curr_addr_step_conn_latch2), .d(curr_addr_step_conn_latch1), .stall(stall), .clk(clk), .rst(rst));
pipeline_latch curr_addr_step_latch3 [31:0] (.q(curr_addr_step_conn_latch3), .d(curr_addr_step_conn_latch2), .stall(stall), .clk(clk), .rst(rst));
pipeline_latch curr_addr_step_latch4 [31:0] (.q(ocurr_addr_step), .d(curr_addr_step_conn_latch3), .stall(stall), .clk(clk), .rst(rst));

// Latch for the current address plus the additional value
wire [31:0] curr_addr_addval_conn_latch1;
wire [31:0] curr_addr_addval_conn_latch2;
pipeline_latch curr_addr_addval_latch1 [31:0] (.q(curr_addr_addval_conn_latch1), .d(curr_addr_addval), .stall(stall), .clk(clk), .rst(rst));
pipeline_latch curr_addr_addval_latch1 [31:0] (.q(curr_addr_addval_conn_latch1), .d(curr_addr_addval), .stall(stall | first_stage_stall), .clk(clk), .rst(rst));
pipeline_latch curr_addr_addval_latch2 [31:0] (.q(curr_addr_addval_conn_latch2), .d(curr_addr_addval_conn_latch1), .stall(stall), .clk(clk), .rst(rst));
pipeline_latch curr_addr_addval_latch3 [31:0] (.q(ocurr_addr_reljmp), .d(curr_addr_addval_conn_latch2), .stall(stall), .clk(clk), .rst(rst));

// Latch for current
wire [31:0] curr_addr_conn_latch1;
wire [31:0] curr_addr_out;
pipeline_latch curr_addr_latch1 [31:0] (.q(curr_addr_conn_latch1), .d(curr_addr), .stall(stall), .clk(clk), .rst(rst));
pipeline_latch curr_addr_latch1 [31:0] (.q(curr_addr_conn_latch1), .d(curr_addr), .stall(stall | first_stage_stall), .clk(clk), .rst(rst));
pipeline_latch curr_addr_latch2 [31:0] (.q(curr_addr_out), .d(curr_addr_conn_latch1), .stall(stall), .clk(clk), .rst(rst));

assign curr_addr_step = curr_addr + 4;
Expand Down
16 changes: 7 additions & 9 deletions src/memory_system.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ module memory_system #(parameter WORD_SIZE = 32)
input [WORD_SIZE-1:0] dmem_data_in,
input [WORD_SIZE-1:0] data_out,
output reg [WORD_SIZE-1:0] data_in,
output imem_stall,
output dmem_stall,
output pc_stall,
output stall,
output first_stage_stall,
output stage_1_stall,
output squash,
input mem_ready,
input jump_taken,
Expand Down Expand Up @@ -77,12 +76,11 @@ module memory_system #(parameter WORD_SIZE = 32)
assign imem_re_en = 1'b1;
assign imem_wr_en = 1'b0;

assign full_imem_stall = imem_stall & ~dmem_ext_mem_op & jump_taken; // Full pipeline stall for the icache if there is not a miss in the dcache and jump is going to be taken
assign imem_stall = ~imem_ready & ~control_hazard & imem_valid_addr;
assign dmem_stall = ~dmem_ready & dmem_valid_addr;
assign stall = dmem_stall | full_imem_stall;
assign first_stage_stall = stall | data_hazard | (imem_stall & control_hazard);

assign pc_stall = (~imem_ready & ~control_hazard & imem_valid_addr) | (control_hazard & imem_cache_miss_stall); // Stall for specifcally the PC counter
assign stage_1_stall = stall | data_hazard; // Stall for specifically the first stage
assign full_dmem_stall = ~dmem_ready & dmem_valid_addr; // will only data mem stall if address if valid and dmem is not ready
assign full_imem_stall = pc_stall & ~dmem_ext_mem_op & jump_taken; // Full pipeline stall for the icache if there is not a miss in the dcache and jump is going to be taken
assign stall = full_dmem_stall | full_imem_stall; // Stall whole pipeline
assign squash = data_hazard | control_hazard;

pipeline_latch dmem_data_output_latch [31:0] (.q(dmem_data_out), .d(input_dmem_data_out), .stall(stall), .clk(clk), .rst(rst));
Expand Down
18 changes: 8 additions & 10 deletions src/proc.sv
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module proc(input [31:0] data_out,

`include "proc_params.h"

// Intruction
// Instruction
wire [31:0] instr;
// Output from ALU operation
wire [31:0] ialu_odata;
Expand All @@ -35,10 +35,8 @@ module proc(input [31:0] data_out,
// Function Value (if there is one)
wire [9:0] func;

// Stall from data memory
wire dmem_stall;
// Stall from instruction memory
wire imem_stall;
wire pc_stall;
// Enables if a jump can be taken
wire en_jmp;
// Enables unconditional jumps
Expand All @@ -55,7 +53,7 @@ module proc(input [31:0] data_out,
wire [31:0] curr_addr_step;
wire [31:0] curr_addr_addval;
wire stall;
wire first_stage_stall;
wire stage_1_stall;
wire jump_taken;
wire control_hazard;
wire data_hazard;
Expand All @@ -77,10 +75,9 @@ module proc(input [31:0] data_out,
.dmem_data_in(data_to_cache),
.data_out(data_out),
.data_in(data_in),
.imem_stall(imem_stall),
.dmem_stall(dmem_stall),
.pc_stall(pc_stall),
.stall(stall),
.first_stage_stall(first_stage_stall),
.stage_1_stall(stage_1_stall),
.squash(squash),
.mem_ready(mem_ready),
.jump_taken(jump_taken),
Expand Down Expand Up @@ -119,8 +116,9 @@ module proc(input [31:0] data_out,
.en_branch(en_branch),
.en_jmp(en_jmp),
.imm(imm_to_addr),
.stall(first_stage_stall),
.imem_stall(imem_stall),
.stall(stall),
.first_stage_stall(stage_1_stall),
.pc_stall(pc_stall),
.clk(clk),
.rst(rst));

Expand Down
64 changes: 64 additions & 0 deletions src/reg_file.sv
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,38 @@ module reg_file(a0, a1, a2, din, reg_wr, d0, d1, clk, rst);
output reg [31:0] d1;
wire [31:0] qn [`REG_NUM-2:0];
reg [`REG_NUM-2:0] we;

wire [31:0] x1_reg;
wire [31:0] x2_reg;
wire [31:0] x3_reg;
wire [31:0] x4_reg;
wire [31:0] x5_reg;
wire [31:0] x6_reg;
wire [31:0] x7_reg;
wire [31:0] x8_reg;
wire [31:0] x9_reg;
wire [31:0] x10_reg;
wire [31:0] x11_reg;
wire [31:0] x12_reg;
wire [31:0] x13_reg;
wire [31:0] x14_reg;
wire [31:0] x15_reg;
wire [31:0] x16_reg;
wire [31:0] x17_reg;
wire [31:0] x18_reg;
wire [31:0] x19_reg;
wire [31:0] x20_reg;
wire [31:0] x21_reg;
wire [31:0] x22_reg;
wire [31:0] x23_reg;
wire [31:0] x24_reg;
wire [31:0] x25_reg;
wire [31:0] x26_reg;
wire [31:0] x27_reg;
wire [31:0] x28_reg;
wire [31:0] x29_reg;
wire [31:0] x30_reg;
wire [31:0] x31_reg;

// registers x1-x31, x0 is the zero register (always holds zero)
reg_dflop x1 [31:0](.q(qn[0]), .d(din), .we(we[0]), .clk(clk), .rst(rst));
Expand Down Expand Up @@ -49,6 +81,38 @@ module reg_file(a0, a1, a2, din, reg_wr, d0, d1, clk, rst);
reg_dflop x30 [31:0](.q(qn[29]), .d(din), .we(we[29]), .clk(clk), .rst(rst));
reg_dflop x31 [31:0](.q(qn[30]), .d(din), .we(we[30]), .clk(clk), .rst(rst));

assign x1_reg = qn[0];
assign x2_reg = qn[1];
assign x3_reg = qn[2];
assign x4_reg = qn[3];
assign x5_reg = qn[4];
assign x6_reg = qn[5];
assign x7_reg = qn[6];
assign x8_reg = qn[7];
assign x9_reg = qn[8];
assign x10_reg = qn[9];
assign x11_reg = qn[10];
assign x12_reg = qn[11];
assign x13_reg = qn[12];
assign x14_reg = qn[13];
assign x15_reg = qn[14];
assign x16_reg = qn[15];
assign x17_reg = qn[16];
assign x18_reg = qn[17];
assign x19_reg = qn[18];
assign x20_reg = qn[19];
assign x21_reg = qn[20];
assign x22_reg = qn[21];
assign x23_reg = qn[22];
assign x24_reg = qn[23];
assign x25_reg = qn[24];
assign x26_reg = qn[25];
assign x27_reg = qn[26];
assign x28_reg = qn[27];
assign x29_reg = qn[28];
assign x30_reg = qn[29];
assign x31_reg = qn[30];

// mux for reg value for d0
always @ (*) begin
case({a0})
Expand Down
49 changes: 0 additions & 49 deletions tests/fix_addr.py

This file was deleted.

69 changes: 69 additions & 0 deletions tests/freedom-bin2hex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Copyright 2018 SiFive, Inc
# SPDX-License-Identifier: Apache-2.0

import argparse
import sys

try:
# Python 3
from itertools import zip_longest
except ImportError:
# Python 2
from itertools import izip_longest as zip_longest


# Copied from https://docs.python.org/3/library/itertools.html
def grouper(iterable, n, fillvalue=None):
"""Collect data into fixed-length chunks or blocks"""
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)


def convert(bit_width, infile, outfile):
byte_width = bit_width // 8
if sys.version_info >= (3, 0):
for row in grouper(infile.read(), byte_width, fillvalue=0):
# Reverse because in Verilog most-significant bit of vectors is first.
hex_row = ''.join('{:02x}'.format(b) for b in reversed(row))
outfile.write(hex_row + '\n')
else:
for row in grouper(infile.read(), byte_width, fillvalue='\x00'):
# Reverse because in Verilog most-significant bit of vectors is first.
hex_row = ''.join('{:02x}'.format(ord(b)) for b in reversed(row))
outfile.write(hex_row + '\n')


def main():
parser = argparse.ArgumentParser(
description='Convert a binary file to a format that can be read in '
'verilog via $readmemh(). By default read from stdin '
'and write to stdout.'
)
if sys.version_info >= (3, 0):
parser.add_argument('infile',
nargs='?',
type=argparse.FileType('rb'),
default=sys.stdin.buffer)
else:
parser.add_argument('infile',
nargs='?',
type=argparse.FileType('rb'),
default=sys.stdin)
parser.add_argument('outfile',
nargs='?',
type=argparse.FileType('w'),
default=sys.stdout)
parser.add_argument('--bit-width', '-w',
type=int,
required=True,
help='How many bits per row.')
args = parser.parse_args()

if args.bit_width % 8 != 0:
sys.exit("Cannot handle non-multiple-of-8 bit width yet.")
convert(args.bit_width, args.infile, args.outfile)


if __name__ == '__main__':
main()
Loading