Compare commits
5 Commits
main
...
parallel_a
Author | SHA1 | Date | |
---|---|---|---|
5cb8b7dd77 | |||
51103c378d | |||
71bc903f14 | |||
3b476cfc32 | |||
02db181281 |
68
.github/workflows/build.yml
vendored
68
.github/workflows/build.yml
vendored
@@ -1,68 +0,0 @@
|
|||||||
name: Build
|
|
||||||
|
|
||||||
on: push
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
|
|
||||||
# lint:
|
|
||||||
# runs-on: ubuntu-latest
|
|
||||||
# steps:
|
|
||||||
# - uses: actions/checkout@master
|
|
||||||
# - uses: chipsalliance/verible-linter-action@main
|
|
||||||
# # with:
|
|
||||||
# # paths: |
|
|
||||||
# # ./src
|
|
||||||
# # ./lib
|
|
||||||
# # ./tests
|
|
||||||
# # extra_args: "--check_syntax=true"
|
|
||||||
|
|
||||||
# enumerate-tests:
|
|
||||||
# name: Enumerate tests
|
|
||||||
# runs-on: ubuntu-latest
|
|
||||||
# outputs:
|
|
||||||
# matrix: ${{ steps.set-matrix.outputs.matrix }}
|
|
||||||
# steps:
|
|
||||||
# - uses: actions/checkout@v2
|
|
||||||
# - id: set-matrix
|
|
||||||
# run: echo "::set-output name=matrix::$(ls tests | grep test_* | jq -R -s -c 'split("\n")[:-1]')"
|
|
||||||
|
|
||||||
test:
|
|
||||||
# needs: enumerate-tests
|
|
||||||
name: Run Test `${{ matrix.test }}`
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
# test: ${{ fromJson(needs.enumerate-tests.outputs.matrix) }}
|
|
||||||
test:
|
|
||||||
- test_basic
|
|
||||||
- test_c
|
|
||||||
max-parallel: 1
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Build executables
|
|
||||||
uses: docker://runtimeverificationinc/riscv-gnu-toolchain:ubuntu-jammy-2024.04.12
|
|
||||||
with:
|
|
||||||
entrypoint: sh
|
|
||||||
args: |
|
|
||||||
-c "\
|
|
||||||
cd tests/${{ matrix.test }} && \
|
|
||||||
make obj && \
|
|
||||||
riscv64-unknown-elf-ld -melf32lriscv -T tb.ld *.o -o tb.elf && \
|
|
||||||
riscv64-unknown-elf-objcopy --target=verilog tb.elf tb.hex && \
|
|
||||||
riscv64-unknown-elf-objdump -xhdtsf tb.elf && \
|
|
||||||
echo "done" \
|
|
||||||
"
|
|
||||||
|
|
||||||
- name: Run Simulation
|
|
||||||
uses: docker://brendanhaines/iverilog:latest
|
|
||||||
with:
|
|
||||||
entrypoint: bash
|
|
||||||
args: |
|
|
||||||
-c "\
|
|
||||||
cd tests/${{ matrix.test }} && \
|
|
||||||
iverilog -g2012 -o tb.out tb.sv ../../src/*.v -Y .sv -I ../../lib && \
|
|
||||||
./tb.out | tee tb.log &&\
|
|
||||||
grep -q "ERROR" tb.log || true &&\
|
|
||||||
grep -q "SUCCESS" tb.log &&\
|
|
||||||
echo "done"
|
|
||||||
"
|
|
20
.gitlab-ci.yml
Normal file
20
.gitlab-ci.yml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
image: ubuntu
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- simulate
|
||||||
|
|
||||||
|
testbench:
|
||||||
|
stage: simulate
|
||||||
|
script:
|
||||||
|
- echo "Installing dependencies..."
|
||||||
|
- apt update && apt install -y make iverilog gcc-10-riscv64-linux-gnu
|
||||||
|
- echo "Running tests..."
|
||||||
|
- make -C tests
|
||||||
|
|
||||||
|
testbench_libraries:
|
||||||
|
stage: simulate
|
||||||
|
script:
|
||||||
|
- echo "Installing dependencies..."
|
||||||
|
- apt update && apt install -y make iverilog
|
||||||
|
- echo "Running tests..."
|
||||||
|
- make -C lib/tb
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "riscv-gnu-toolchain"]
|
||||||
|
path = riscv-gnu-toolchain
|
||||||
|
url = https://github.com/riscv-collab/riscv-gnu-toolchain.git
|
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@@ -2,7 +2,6 @@
|
|||||||
"recommendations": [
|
"recommendations": [
|
||||||
"mshr-h.veriloghdl",
|
"mshr-h.veriloghdl",
|
||||||
"zhwu95.riscv",
|
"zhwu95.riscv",
|
||||||
"hediet.vscode-drawio",
|
"hediet.vscode-drawio"
|
||||||
"sunshaoce.risc-v"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
43
README.md
43
README.md
@@ -1,36 +1,25 @@
|
|||||||
|

|
||||||
|
|
||||||
# RISC-V CPU
|
# RISC-V CPU
|
||||||
|
|
||||||
Short Term To Do:
|
Short Term To Do:
|
||||||
- [ ] add stalls for memory access
|
* add stalls for memory access
|
||||||
- [ ] use AXI for memory access (depends on AXIL memory module for test)
|
* use AXI for memory access (depends on AXIL memory module for test)
|
||||||
- [ ] add tests for non-pipelined case
|
* add tests for non-pipelined case
|
||||||
- [ ] get C working (may depend on memory stalls)
|
* get C working (may depend on memory stalls)
|
||||||
|
|
||||||
Desired features:
|
Desired features:
|
||||||
- [ ] 1- or 5-stage pipeline selectable via parameter
|
* 1- or 5-stage pipeline selectable via parameter
|
||||||
- [ ] AXI-lite Master for both instruction and data memory
|
* AXI-lite Master for both instruction and data memory
|
||||||
- [ ] 32, 64, (or 128?) bit word size
|
* 32, 64, (or 128?) bit word size
|
||||||
- [ ] floating point
|
* floating point
|
||||||
- [ ] multiplication
|
* multiplication
|
||||||
- [ ] division
|
* division
|
||||||
- [ ] instruction and data caches
|
* instruction and data caches
|
||||||
- [ ] JTAG debug probe
|
* JTAG debug probe
|
||||||
|
|
||||||
## Development
|
## Installation
|
||||||
|
Run `setup.sh` to install GCC
|
||||||
### Testing
|
|
||||||
|
|
||||||
I'm using [act](https://github.com/nektos/act) for local testing. No special installation is required since everything gets built and tested in containers as part of the CI actions.
|
|
||||||
|
|
||||||
To run the tests, use
|
|
||||||
```bash
|
|
||||||
act push
|
|
||||||
```
|
|
||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
* [AXI4 Protocol Specification](https://developer.arm.com/documentation/ihi0022/e/AMBA-AXI3-and-AXI4-Protocol-Specification?lang=en)
|
* [AXI4 Protocol Specification](https://developer.arm.com/documentation/ihi0022/e/AMBA-AXI3-and-AXI4-Protocol-Specification?lang=en)
|
||||||
* [JTAG Bus Description](https://web.archive.org/web/20230314233136/http://www.interfacebus.com/Design_Connector_JTAG_Bus.html)
|
|
||||||
* [1149.1-2013 - IEEE Standard for Test Access Port and Boundary-Scan Architecture](https://ieeexplore.ieee.org/document/6515989)
|
|
||||||
|
|
||||||
## Attribution
|
|
||||||
* [Icon](https://www.flaticon.com/free-icon/cpu_543275)
|
|
1
docs/cpu.drawio
Normal file
1
docs/cpu.drawio
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<mxfile host="www.draw.io" modified="2021-07-04T02:03:34.409Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36" etag="gyPD3FephFzBolRvCJxz" version="14.8.4" type="device"><diagram id="K6ND4OlvUQiSsjvqaGL3" name="Page-1">7Vpbc5s4FP41ntl9iAchwPjRl2SbnWa2M9mZbR8VkA1dGXmEnNj99SuMMCAJ16kh0G384EEHSaDvfOeig0Zwsdn/wdA2eqAhJiPbCvcjuBzZ9tQH4j8THHKBa8FcsGZxmItAKXiMv2EptKR0F4c4rXXklBIeb+vCgCYJDnhNhhijL/VuK0rqT92iNdYEjwEiuvSfOORRLvVdq5R/wPE6Kp4MLHlng4rOUpBGKKQvFRG8HcEFo5TnV5v9ApMMuwKXfNxdw93TizGc8EsGPN18Q/HKWzjLP7nvEJAs/rq/sZ18mmdEdnLF8m35oYCA0V0S4mwWawTnL1HM8eMWBdndF6FzIYv4hogWEJchSqNj36yxiglZUEKZaCc0ESPm8nGYcbxvXAg4wSNohekGc3YQXeQATwIqGVXg+1Kqx/GlLKqoxi6ESFJifZq5RE1cSOBeASK0WwaxitvIhqvVyg4CIU85o//i9hGdKIhCHVJoGSD1ukLUnnSLaOhiP3Q6RBROVZLqkALHAOm0M0i9nxxShaQGjjqeAVDQmdlPNfxwKGKHbFLGI7qmCSK3pXReR7js85HSrcT1K+b8IAMh2nFaRx3vY/45Gz52ZetL5c5yL2c+Ng5FIxHLrQzKml+q98phx1YxLuWI8VkWRIUgIChN46AQ38WkeKUchmzt5zUroKI7FuAzkBYRHrE15mf6uWamMEwQj5/r79G63oFmSAFlePx8nTm1YCF+3UIcg4WYXI7TmcvRgFoijoTkAW/o8cUXKIhw77idEDgo7aqztt8SOaghd58Iv7oLeEyT4QHoDw0/AN99c9u+2bnQN8M+fbO+nWkwnA8oCQlmQzMdYNjNvLHp6Gnhu+lcaTruhaZj95rWuJrtzD7fjzLy3Yl/cX3zUViDuPztAaUcs9/7JAqo0KQkjZkoFyo8jdA2e+iK4L3s3ToJGv2ANYbQkaZ3sb7lbJ9oLF6mUh9RfMpkOp64vmdbnj/1XNeG9RlzWspJqgWkYt6iI12tUsw1op0Wc0WmaPXJJWts/5DXsf8nbgdMr/Q7x6FiaehQ6bDN2JM201SrOqn1S7U/vK5/UcFq7K8VGGr9xUW+wlaJr/tcZYvkEaG5+ZNIVLx1djWUvEXdMwGv78RFLxm+NnyZAgBOwgab1cVXhinxqOITA/DGXu3n5/elK3PHPqz9Osj0z0QqT9e0qTp8El4Zz6BimI6lUChf0JkA1hQYVS4OIBIC30RjSV3VGVyRiJm4PuTkrEV6+21Eu++SS/s40kCutoij82aJn3brrEZERR5CyRCihqOC1H+l6KfMPAeeeF5axm8INNfGC1AnmfpJ7dJwoc4DJm9r0QD0S83Jr0zNboIEtBVK/Wgqo02kfuVs4OZrN2mOagPf2UQ53tn+3WyigP5p+5j6q+nSgtE0fUL9h0E1VzBEweLcVDUIwu7OW9hmBA2bp0eCnvF76e91TqehwNJ97Q/Cwdf+wFTjnqyB/J1Rnxw/c9LdlgjulHWRgZU/YO/fbWy9lJStfIuZ4WSCWDivY2I8tWM4v4dIvE4yWxJAiQ0FnGcwxgEiM3ljE4fh0d5NSqirqXZWsAOlXKoTuzOd6NT+JByPkOipna6SNqFeiT1g5bDWZDbzvUJeuG3Qggq0nNlw7s14OLOzkxT6aR2pArsHFZRQaypZOLOJc9eOIQD1QIbbmRZEszzCnIeE8hw4vP0P</diagram></mxfile>
|
Binary file not shown.
Before Width: | Height: | Size: 390 KiB |
53
lib/axil_ata.sv
Normal file
53
lib/axil_ata.sv
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
module axil_ata(
|
||||||
|
|
||||||
|
///// AXI4-Lite Slave /////
|
||||||
|
|
||||||
|
// Write address
|
||||||
|
input logic axil_awvalid,
|
||||||
|
output logic axil_awready,
|
||||||
|
input logic [ADDR_WIDTH-1:0] axil_awaddr,
|
||||||
|
input logic [2:0] axil_awprot,
|
||||||
|
|
||||||
|
// Write data
|
||||||
|
input logic axil_wvalid,
|
||||||
|
output logic axil_wready,
|
||||||
|
input logic [DATA_WIDTH-1:0] axil_wdata,
|
||||||
|
input logic [DATA_WIDTH/8 - 1:0] axil_wstrb,
|
||||||
|
|
||||||
|
// Write response
|
||||||
|
output logic axil_bvalid,
|
||||||
|
input logic axil_bready,
|
||||||
|
output logic [1:0] axil_bresp,
|
||||||
|
|
||||||
|
// Read address
|
||||||
|
input logic axil_arvalid,
|
||||||
|
output logic axil_arready,
|
||||||
|
input logic [ADDR_WIDTH-1:0] axil_araddr,
|
||||||
|
input logic [2:0] axil_arprot,
|
||||||
|
|
||||||
|
// Read data
|
||||||
|
output logic axil_rvalid,
|
||||||
|
input logic axil_rready,
|
||||||
|
output logic [DATA_WIDTH-1:0] axil_rdata,
|
||||||
|
output logic [1:0] axil_rresp,
|
||||||
|
|
||||||
|
///// Parallel ATA Master /////
|
||||||
|
output logic ata_n_reset, // reset
|
||||||
|
inout wire [15:0] ata_data, // data
|
||||||
|
output logic ata_n_diow, // write strobe
|
||||||
|
output logic ata_n_dior, // read strobe
|
||||||
|
input wire ata_iordy, //
|
||||||
|
input wire ata_irq, // interrupt request
|
||||||
|
output logic [2:0] ata_addr, // address
|
||||||
|
output logic [1:0] ata_n_cs, // chip select
|
||||||
|
input wire ata_activity, // LED driver
|
||||||
|
xx wire ata_cable_select, //
|
||||||
|
xx wire ata_dmarq, // DMA request
|
||||||
|
xx wire ata_ddack, // DMA acknowledge
|
||||||
|
xx wire ata_gpio_dma66_detect, //
|
||||||
|
xx wire ata_n_iocs16 // IO ChipSelect 16
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
@@ -7,7 +7,7 @@ module axil_wb_bridge #(
|
|||||||
input logic clk,
|
input logic clk,
|
||||||
input logic reset,
|
input logic reset,
|
||||||
|
|
||||||
///// AXI4-Lite /////
|
///// AXI4-Lite Slave /////
|
||||||
|
|
||||||
// Write address
|
// Write address
|
||||||
input logic axil_awvalid,
|
input logic axil_awvalid,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
module skidbuffer #(
|
module axis_skidbuffer #(
|
||||||
parameter WIDTH = 1
|
parameter WIDTH = 1
|
||||||
)(
|
)(
|
||||||
input logic clk,
|
input logic clk,
|
21
lib/tb/axil_ata_tb.sv
Normal file
21
lib/tb/axil_ata_tb.sv
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
`include "bh_assert.sv"
|
||||||
|
`timescale 1ns/1ps
|
||||||
|
|
||||||
|
import bh_assert::bh_assert_equal;
|
||||||
|
import bh_assert::bh_assert_stats;
|
||||||
|
import bh_assert::bh_info;
|
||||||
|
|
||||||
|
module axil_ata_tb();
|
||||||
|
|
||||||
|
axil_ata dut();
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$dumpfile("axil_ata_tb.vcd");
|
||||||
|
$dumpvars(0, axil_ata_tb);
|
||||||
|
|
||||||
|
#10
|
||||||
|
bh_assert_stats();
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
@@ -255,6 +255,10 @@ initial begin
|
|||||||
#10
|
#10
|
||||||
bh_assert_stats();
|
bh_assert_stats();
|
||||||
$finish;
|
$finish;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: add more exhaustive testing
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
@@ -4,7 +4,7 @@
|
|||||||
import bh_assert::bh_assert_equal;
|
import bh_assert::bh_assert_equal;
|
||||||
import bh_assert::bh_assert_stats;
|
import bh_assert::bh_assert_stats;
|
||||||
|
|
||||||
module skidbuffer_tb();
|
module axis_skidbuffer_tb();
|
||||||
parameter WIDTH = 15;
|
parameter WIDTH = 15;
|
||||||
parameter TEST_LIST_LENGTH = 256;
|
parameter TEST_LIST_LENGTH = 256;
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ module skidbuffer_tb();
|
|||||||
wire out_valid;
|
wire out_valid;
|
||||||
logic out_ready = 0;
|
logic out_ready = 0;
|
||||||
|
|
||||||
skidbuffer #(
|
axis_skidbuffer #(
|
||||||
.WIDTH(WIDTH)
|
.WIDTH(WIDTH)
|
||||||
) dut (
|
) dut (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
@@ -40,8 +40,8 @@ module skidbuffer_tb();
|
|||||||
always #5 clk = !clk;
|
always #5 clk = !clk;
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
$dumpfile("skidbuffer_tb.vcd");
|
$dumpfile("axis_skidbuffer_tb.vcd");
|
||||||
$dumpvars(0, skidbuffer_tb);
|
$dumpvars(0, axis_skidbuffer_tb);
|
||||||
|
|
||||||
for (i=0; i<TEST_LIST_LENGTH; i=i+1) begin
|
for (i=0; i<TEST_LIST_LENGTH; i=i+1) begin
|
||||||
in_list[i] = $urandom();
|
in_list[i] = $urandom();
|
||||||
@@ -71,8 +71,10 @@ module skidbuffer_tb();
|
|||||||
end
|
end
|
||||||
|
|
||||||
if (reset == 0 && out_valid && out_ready) begin
|
if (reset == 0 && out_valid && out_ready) begin
|
||||||
bh_assert_equal(out, in_list[out_count], $sformatf("Output value [%3d]", out_count));
|
if (out_count < TEST_LIST_LENGTH) begin
|
||||||
out_count <= out_count + 1;
|
bh_assert_equal(out, in_list[out_count], $sformatf("Output value [%3d]", out_count));
|
||||||
|
out_count <= out_count + 1;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
1
riscv-gnu-toolchain
Submodule
1
riscv-gnu-toolchain
Submodule
Submodule riscv-gnu-toolchain added at 96d9f40c9d
7
setup.sh
Executable file
7
setup.sh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
sudo apt-get install -y autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev
|
||||||
|
|
||||||
|
SCRIPT=$(realpath "$0")
|
||||||
|
SCRIPTPATH=$(dirname "$SCRIPT")
|
||||||
|
cd $SCRIPTPATH/riscv-gnu-toolchain
|
||||||
|
./configure --prefix=$SCRIPTPATH/toolchain/riscv --enable-multilib
|
||||||
|
make
|
62
src/bh_cpu.v
62
src/bh_cpu.v
@@ -120,6 +120,19 @@ reg s_if_stall = 0;
|
|||||||
reg [31:0] s_if_next_pc;
|
reg [31:0] s_if_next_pc;
|
||||||
reg [31:0] s_if_inst;
|
reg [31:0] s_if_inst;
|
||||||
|
|
||||||
|
always @(*) begin
|
||||||
|
s_if_stall = s_id_stall;
|
||||||
|
|
||||||
|
if (s_ex_take_branch) begin
|
||||||
|
s_if_next_pc = s_ex_branch_addr;
|
||||||
|
end else begin
|
||||||
|
s_if_next_pc = r_if_pc + 4;
|
||||||
|
end
|
||||||
|
|
||||||
|
mem_inst_addr = r_if_pc;
|
||||||
|
s_if_inst = mem_inst_data;
|
||||||
|
end
|
||||||
|
|
||||||
// ID
|
// ID
|
||||||
reg s_id_stall;
|
reg s_id_stall;
|
||||||
reg [6:0] s_id_opcode;
|
reg [6:0] s_id_opcode;
|
||||||
@@ -164,39 +177,7 @@ localparam ALUOP_ADD = 4'b0000,
|
|||||||
ALUOP_SLT = 4'b1000,
|
ALUOP_SLT = 4'b1000,
|
||||||
ALUOP_SLTU = 4'b1001;
|
ALUOP_SLTU = 4'b1001;
|
||||||
|
|
||||||
// EX
|
|
||||||
reg s_ex_stall = 0;
|
|
||||||
reg [31:0] s_ex_data1, s_ex_data2;
|
|
||||||
reg [31:0] s_ex_alu_out;
|
|
||||||
reg s_ex_alu_zero;
|
|
||||||
reg s_ex_take_branch;
|
|
||||||
reg [31:0] s_ex_branch_addr;
|
|
||||||
reg [31:0] s_ex_ra;
|
|
||||||
|
|
||||||
// MEM
|
|
||||||
reg s_mem_stall = 0;
|
|
||||||
reg s_mem_bp;
|
|
||||||
reg [31:0] s_mem_load_data;
|
|
||||||
|
|
||||||
// WB
|
|
||||||
reg [31:0] s_wb_data;
|
|
||||||
reg s_wb_write;
|
|
||||||
|
|
||||||
// IF
|
|
||||||
always @(*) begin
|
|
||||||
s_if_stall = s_id_stall;
|
|
||||||
|
|
||||||
if (s_ex_take_branch) begin
|
|
||||||
s_if_next_pc = s_ex_branch_addr;
|
|
||||||
end else begin
|
|
||||||
s_if_next_pc = r_if_pc + 4;
|
|
||||||
end
|
|
||||||
|
|
||||||
mem_inst_addr = r_if_pc;
|
|
||||||
s_if_inst = mem_inst_data;
|
|
||||||
end
|
|
||||||
|
|
||||||
// ID
|
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
s_id_invalid = 0;
|
s_id_invalid = 0;
|
||||||
s_id_store = 0;
|
s_id_store = 0;
|
||||||
@@ -351,6 +332,14 @@ always @(*) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
// EX
|
// EX
|
||||||
|
reg s_ex_stall = 0;
|
||||||
|
reg [31:0] s_ex_data1, s_ex_data2;
|
||||||
|
reg [31:0] s_ex_alu_out;
|
||||||
|
reg s_ex_alu_zero;
|
||||||
|
reg s_ex_take_branch;
|
||||||
|
reg [31:0] s_ex_branch_addr;
|
||||||
|
reg [31:0] s_ex_ra;
|
||||||
|
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
s_ex_stall = s_mem_stall;
|
s_ex_stall = s_mem_stall;
|
||||||
|
|
||||||
@@ -405,6 +394,10 @@ always @(*) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
// MEM
|
// MEM
|
||||||
|
reg s_mem_stall = 0;
|
||||||
|
reg s_mem_bp;
|
||||||
|
reg [31:0] s_mem_load_data;
|
||||||
|
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
s_mem_stall = 0; // TODO: add stall logic when actually reading/writing
|
s_mem_stall = 0; // TODO: add stall logic when actually reading/writing
|
||||||
s_mem_bp = 0;
|
s_mem_bp = 0;
|
||||||
@@ -424,6 +417,9 @@ always @(*) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
// WB
|
// WB
|
||||||
|
reg [31:0] s_wb_data;
|
||||||
|
reg s_wb_write;
|
||||||
|
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
|
|
||||||
// load instructions do not use output of alu in wb
|
// load instructions do not use output of alu in wb
|
||||||
@@ -479,8 +475,6 @@ always @(posedge clk) begin: pipeline_update
|
|||||||
end
|
end
|
||||||
|
|
||||||
end else begin
|
end else begin
|
||||||
// $display("%0t:\tPC=0x%h", $time, s_if_next_pc);
|
|
||||||
|
|
||||||
// IF
|
// IF
|
||||||
if (!s_if_stall) begin
|
if (!s_if_stall) begin
|
||||||
r_if_pc <= s_if_next_pc;
|
r_if_pc <= s_if_next_pc;
|
||||||
|
6
tests/.gitignore
vendored
6
tests/.gitignore
vendored
@@ -1,3 +1,3 @@
|
|||||||
**/*.out
|
*.out
|
||||||
**/*.vcd
|
*.vcd
|
||||||
**/*.log
|
*.log
|
18
tests/Makefile
Normal file
18
tests/Makefile
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
all: verify
|
||||||
|
|
||||||
|
BENCH ?= $(sort $(dir $(wildcard test_*/)))
|
||||||
|
|
||||||
|
# override bench to disable test_c
|
||||||
|
BENCH = test_basic
|
||||||
|
|
||||||
|
verify:
|
||||||
|
$(foreach dir, $(BENCH), make -C $(dir) verify;)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(foreach dir, $(BENCH), make -C $(dir) clean;)
|
||||||
|
|
||||||
|
help:
|
||||||
|
$(info BENCH options: [${BENCH}])
|
||||||
|
|
||||||
|
.SECONDARY:
|
||||||
|
.PHONY: all clean verify help
|
@@ -2,10 +2,10 @@
|
|||||||
[*] GTKWave Analyzer v3.3.86 (w)1999-2017 BSI
|
[*] GTKWave Analyzer v3.3.86 (w)1999-2017 BSI
|
||||||
[*] Wed Aug 11 06:10:48 2021
|
[*] Wed Aug 11 06:10:48 2021
|
||||||
[*]
|
[*]
|
||||||
[dumpfile] "/home/brendan/Documents/Projects/0039_cpu/testbench/basic_test/tb.vcd"
|
[dumpfile] "/home/brendan/Documents/projects/cpu/tests/test_basic/tb.vcd"
|
||||||
[dumpfile_mtime] "Wed Aug 11 06:09:59 2021"
|
[dumpfile_mtime] "Wed Aug 11 06:09:59 2021"
|
||||||
[dumpfile_size] 511500
|
[dumpfile_size] 511500
|
||||||
[savefile] "/home/brendan/Documents/Projects/0039_cpu/testbench/testbench_tb.gtkw"
|
[savefile] "/home/brendan/Documents/projects/cpu/tests/basic_test.gtkw"
|
||||||
[timestart] 0
|
[timestart] 0
|
||||||
[size] 1920 1052
|
[size] 1920 1052
|
||||||
[pos] -1970 -28
|
[pos] -1970 -28
|
@@ -11,15 +11,15 @@ OBJ = $(notdir $(SOURCE_AS:.S=.o))
|
|||||||
OBJ += $(notdir $(SOURCE_C:.c=.o))
|
OBJ += $(notdir $(SOURCE_C:.c=.o))
|
||||||
|
|
||||||
# Software compilation
|
# Software compilation
|
||||||
CC = riscv64-unknown-elf-gcc
|
CC = riscv64-linux-gnu-gcc
|
||||||
CFLAGS = -march=rv32i -mabi=ilp32
|
CFLAGS = -march=rv32i -mabi=ilp32
|
||||||
|
|
||||||
CPPFLAGS =
|
CPPFLAGS =
|
||||||
|
|
||||||
AS = riscv64-unknown-elf-as
|
AS = riscv64-linux-gnu-as
|
||||||
ASFLAGS = -march=rv32i -mabi=ilp32
|
ASFLAGS = -march=rv32i -mabi=ilp32
|
||||||
|
|
||||||
LD = riscv64-unknown-elf-ld
|
LD = riscv64-linux-gnu-ld
|
||||||
LDFLAGS = -melf32lriscv_ilp32
|
LDFLAGS = -melf32lriscv_ilp32
|
||||||
|
|
||||||
# $(info $$TESTBENCH_V is [${TESTBENCH_V}])
|
# $(info $$TESTBENCH_V is [${TESTBENCH_V}])
|
||||||
@@ -40,7 +40,7 @@ LDFLAGS = -melf32lriscv_ilp32
|
|||||||
$(LD) $(LDFLAGS) -T $^ -o $@
|
$(LD) $(LDFLAGS) -T $^ -o $@
|
||||||
|
|
||||||
%.hex: %.elf
|
%.hex: %.elf
|
||||||
riscv64-unknown-elf-objcopy --target=verilog $< $@
|
riscv64-linux-gnu-objcopy --target=verilog $< $@
|
||||||
|
|
||||||
# Hardware compilation
|
# Hardware compilation
|
||||||
%.out: %.sv $(SOURCE_V)
|
%.out: %.sv $(SOURCE_V)
|
||||||
@@ -57,7 +57,5 @@ verify: $(LOGS)
|
|||||||
clean:
|
clean:
|
||||||
rm -rf *.vcd *.log *.out *.hex
|
rm -rf *.vcd *.log *.out *.hex
|
||||||
|
|
||||||
obj: $(OBJ)
|
|
||||||
|
|
||||||
.SECONDARY: %.log %.vcd
|
.SECONDARY: %.log %.vcd
|
||||||
.PHONY: all clean verify obj
|
.PHONY: all clean verify
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
# basic_test
|
# basic_test
|
||||||
|
|
||||||
Verify basic usage of all instructions. Includes tests to ensure pipeline stalls sufficiently for correctness but does not test for unnecessary/excessive stalls.
|
Verify basic usage of all instructions. Includes tests to ensure pipeline stalls sufficiently for correctness but does not test for unnecessary stalls.
|
||||||
|
|
||||||
Currently store/load does not implement proper stalling so these operations are padded with `nop`
|
Currently store/load does not implement proper stalling so these operations are padded with nop
|
@@ -31,7 +31,7 @@ initial $readmemh("tb.hex", mem);
|
|||||||
// Instruction Memory
|
// Instruction Memory
|
||||||
wire [31:0] mem_inst_addr;
|
wire [31:0] mem_inst_addr;
|
||||||
reg [31:0] mem_inst_data;
|
reg [31:0] mem_inst_data;
|
||||||
always_comb begin
|
always @(*) begin
|
||||||
if (mem_inst_addr < MEM_LENGTH - 3) begin
|
if (mem_inst_addr < MEM_LENGTH - 3) begin
|
||||||
mem_inst_data[ 7: 0] = mem[mem_inst_addr+0];
|
mem_inst_data[ 7: 0] = mem[mem_inst_addr+0];
|
||||||
mem_inst_data[15: 8] = mem[mem_inst_addr+1];
|
mem_inst_data[15: 8] = mem[mem_inst_addr+1];
|
||||||
|
@@ -10,18 +10,18 @@ SOURCE_AS = $(wildcard *.S)
|
|||||||
OBJ = $(notdir $(SOURCE_AS:.S=.o))
|
OBJ = $(notdir $(SOURCE_AS:.S=.o))
|
||||||
OBJ += $(notdir $(SOURCE_C:.c=.o))
|
OBJ += $(notdir $(SOURCE_C:.c=.o))
|
||||||
|
|
||||||
CC = riscv64-unknown-elf-gcc
|
CC = riscv64-linux-gnu-gcc
|
||||||
CFLAGS = -march=rv32i -mabi=ilp32
|
CFLAGS = -march=rv32i -mabi=ilp32
|
||||||
# CFLAGS = -march=rv64i -mabi=lp64
|
# CFLAGS = -march=rv64i -mabi=lp64
|
||||||
# CFLAGS += -nostdlib -lgcc
|
# CFLAGS += -nostdlib -lgcc
|
||||||
|
|
||||||
CPPFLAGS =
|
CPPFLAGS =
|
||||||
|
|
||||||
AS = riscv64-unknown-elf-as
|
AS = riscv64-linux-gnu-as
|
||||||
ASFLAGS = -march=rv32i -mabi=ilp32
|
ASFLAGS = -march=rv32i -mabi=ilp32
|
||||||
# ASFLAGS = -march=rv64i -mabi=lp64
|
# ASFLAGS = -march=rv64i -mabi=lp64
|
||||||
|
|
||||||
LD = riscv64-unknown-elf-ld
|
LD = riscv64-linux-gnu-ld
|
||||||
LDFLAGS = -melf32lriscv_ilp32
|
LDFLAGS = -melf32lriscv_ilp32
|
||||||
# LDFLAGS =
|
# LDFLAGS =
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ LDFLAGS = -melf32lriscv_ilp32
|
|||||||
$(LD) $(LDFLAGS) -T $^ -o $@
|
$(LD) $(LDFLAGS) -T $^ -o $@
|
||||||
|
|
||||||
%.hex: %.elf
|
%.hex: %.elf
|
||||||
riscv64-unknown-elf-objcopy --target=verilog $< $@
|
riscv64-linux-gnu-objcopy --target=verilog $< $@
|
||||||
|
|
||||||
%.out: %.sv $(SOURCE_V)
|
%.out: %.sv $(SOURCE_V)
|
||||||
iverilog -g2012 -o $@ $^
|
iverilog -g2012 -o $@ $^
|
||||||
@@ -62,8 +62,6 @@ verify: $(LOGS)
|
|||||||
clean:
|
clean:
|
||||||
rm -rf *.vcd *.log *.out *.hex
|
rm -rf *.vcd *.log *.out *.hex
|
||||||
|
|
||||||
obj: $(OBJ)
|
|
||||||
|
|
||||||
.SECONDARY: %.log %.vcd
|
.SECONDARY: %.log %.vcd
|
||||||
.PHONY: all clean verify obj
|
.PHONY: all clean verify
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
# C test
|
# basic_test
|
||||||
|
|
||||||
Verify basic ability to use C
|
Verify basic usage of all instructions. Includes tests to ensure pipeline stalls sufficiently for correctness but does not test for unnecessary stalls.
|
||||||
|
|
||||||
Currently all C functions fail because store/load do not stall properly.
|
Currently store/load does not implement proper stalling so these operations are padded with nop
|
@@ -1,6 +1,6 @@
|
|||||||
#include <stdint.h>
|
// #include <stdint.h>
|
||||||
|
|
||||||
uint32_t addathing(uint32_t a)
|
unsigned int addathing(unsigned int a)
|
||||||
{
|
{
|
||||||
return a + 0x29;
|
return a + 0x29;
|
||||||
}
|
}
|
@@ -1,4 +1,5 @@
|
|||||||
OUTPUT_ARCH( "riscv" )
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
@@ -13,7 +14,6 @@ SECTIONS
|
|||||||
{
|
{
|
||||||
/* . = ALIGN(4); */
|
/* . = ALIGN(4); */
|
||||||
_text = .;
|
_text = .;
|
||||||
*(.text.startup)
|
|
||||||
*(.text*)
|
*(.text*)
|
||||||
*(.rodata*)
|
*(.rodata*)
|
||||||
_etext = .;
|
_etext = .;
|
||||||
|
@@ -31,7 +31,7 @@ initial $readmemh("tb.hex", mem);
|
|||||||
// Instruction Memory
|
// Instruction Memory
|
||||||
wire [31:0] mem_inst_addr;
|
wire [31:0] mem_inst_addr;
|
||||||
reg [31:0] mem_inst_data;
|
reg [31:0] mem_inst_data;
|
||||||
always_comb begin
|
always @(*) begin
|
||||||
if (mem_inst_addr < MEM_LENGTH - 3) begin
|
if (mem_inst_addr < MEM_LENGTH - 3) begin
|
||||||
mem_inst_data[ 7: 0] = mem[mem_inst_addr+0];
|
mem_inst_data[ 7: 0] = mem[mem_inst_addr+0];
|
||||||
mem_inst_data[15: 8] = mem[mem_inst_addr+1];
|
mem_inst_data[15: 8] = mem[mem_inst_addr+1];
|
||||||
|
@@ -1,23 +1,17 @@
|
|||||||
.global _start
|
.global _start
|
||||||
|
|
||||||
.section .text.startup # start vector
|
.global addathing
|
||||||
j _start
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
|
|
||||||
.text
|
.text
|
||||||
_start:
|
_start:
|
||||||
|
|
||||||
addi a0, zero, 0x134
|
addi a0, zero, 0x134
|
||||||
addi a1, zero, 0x0
|
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
# call addathing # c compilation has sw/lw instructions. Missing stalls break execution
|
call addathing
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
|
Reference in New Issue
Block a user