Skip to content
Closed
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
66 changes: 51 additions & 15 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ on:
pull_request:
push:
branches:
- main
- jalr-branch

permissions:
contents: read
packages: write

jobs:
build_ci_image:
timeout-minutes: 30
runs-on: ubuntu-latest
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
Expand Down Expand Up @@ -60,6 +61,7 @@ jobs:
type=registry,ref=ghcr.io/utoss/risc-v:buildcache,mode=max

build_and_test:
timeout-minutes: 30
needs: build_ci_image
runs-on: ubuntu-latest
container:
Expand All @@ -77,21 +79,55 @@ jobs:
id: build-testbench
run: make build_tb

- name: Run testbench
run: make run_tb
# - name: Run testbench
# run: make run_tb

- name: Upload VCD files
uses: actions/upload-artifact@v4
if: steps.build-testbench.outcome == 'success'
with:
name: vcd-files
path: test/vcd/*.vcd
retention-days: 7
# - name: Upload VCD files
# uses: actions/upload-artifact@v4
# if: steps.build-testbench.outcome == 'success'
# with:
# name: vcd-files
# path: test/vcd/*.vcd
# retention-days: 7

# - name: Upload VVP files
# uses: actions/upload-artifact@v4
# if: steps.build-top.outcome == 'success'
# with:
# name: vvp-files
# path: out/*.vvp
# retention-days: 7

riscof:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we'll need to merge #44 first before this step will work; ill do that tomorrow

timeout-minutes: 30
needs: [build_ci_image, build_and_test]
runs-on: ubuntu-latest
container:
image: ${{ needs.build_ci_image.outputs.image-primary-tag }}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Build DUT
run: make riscof_build_dut

- name: Validate YAML
run: make riscof_validateyaml

- name: Clone arch-test
run: make riscof_clone_archtest

- name: Run RISCOF
run: make riscof_run
continue-on-error: true

- name: Upload VVP files
- name: Upload RISCOF report
if: always()
uses: actions/upload-artifact@v4
if: steps.build-top.outcome == 'success'
with:
name: vvp-files
path: out/*.vvp
retention-days: 7
name: riscof-report
path: |
riscof/riscof_work/report.html
riscof/riscof_work/style.css
retention-days: 7
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
SRC_DIR := src
OUTPUT := out/top.vvp
IVERILOG := iverilog
# /opt/iverilog-12/bin/iverilog
#iverilog
VVP := vvp
# /opt/iverilog-12/bin/vvp
#vvp

SRCS := $(shell find $(SRC_DIR) -name "*.sv" -o -name "*.v")

Expand Down
45 changes: 36 additions & 9 deletions src/ControlFSM.sv
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ module ControlFSM(
input opcode_t opcode,
input wire clk,
input wire reset,
input wire zero_flag,
input wire zero_flag,
output adr_src_t AdrSrc,
output reg IRWrite,
output reg RegWrite,
output reg PCUpdate,
output pc_src_t pc_src,
output pc_src_t pc_src,
output reg MemWrite,
output reg Branch,
output alu_src_a_t ALUSrcA,
Expand All @@ -37,11 +37,15 @@ module ControlFSM(
parameter MEMREAD = 4'b1000;
parameter MEMWB = 4'b1001;
parameter BRANCHIFEQ = 4'b1010;


//new states for lui and auipc
parameter LUI = 4'b1011;
parameter AUIPC = 4'b1100;


//new state for JALR
parameter JALR_CALC = 4'b1101; // calculate rs1 + imm, store in alu_out
parameter JALR_STEP2 = 4'b1110; // link and use alu_out to update PC

//declare state registers
reg [3:0] current_state, next_state;
Expand Down Expand Up @@ -69,6 +73,8 @@ module ControlFSM(

else if (opcode == UType_lui) next_state = LUI;

else if (opcode == IType_jalr) next_state = JALR_CALC;

else next_state = DECODE;

end
Expand All @@ -93,6 +99,10 @@ module ControlFSM(

end

JALR_CALC: next_state = JALR_STEP2;

JALR_STEP2: next_state = ALUWB;

BRANCHIFEQ: next_state = FETCH;

ALUWB: next_state = FETCH;
Expand All @@ -112,7 +122,7 @@ module ControlFSM(
//output logic
always@(*) begin
Branch <= 1'b0;
pc_src <= 1'b0;
pc_src <= PC_SRC__INCREMENT;
PCUpdate <= 1'b0;
IRWrite <= 1'b0;
MemWrite <= 1'b0;
Expand All @@ -125,7 +135,7 @@ module ControlFSM(

AdrSrc <= ADR_SRC__PC;
IRWrite <= 1'b1;
PCUpdate <= 1'b1;
PCUpdate <= 1'b1;

end

Expand Down Expand Up @@ -175,10 +185,26 @@ module ControlFSM(
ALUSrcB <= ALU_SRC_B__4;
ALUOp <= 2'b00;
ResultSrc <= RESULT_SRC__ALU_OUT;
PCUpdate <= 1'b1;
pc_src <= PC_SRC__JUMP;
PCUpdate <= 1'b1;

end

JALR_CALC: begin
ALUSrcA <= ALU_SRC_A__RD1; // rs1
ALUSrcB <= ALU_SRC_B__IMM_EXT; // + imm
ALUOp <= 2'b00;
end

JALR_STEP2: begin
ALUSrcA <= ALU_SRC_A__OLD_PC; // Calculate link = pc_old + 4, write back in ALUWB
ALUSrcB <= ALU_SRC_B__4;
ALUOp <= 2'b00;
ResultSrc <= RESULT_SRC__ALU_OUT;
pc_src <= PC_SRC__ALU_RESULT; // fetch (alu_out & ~1) for new PC
PCUpdate <= 1'b1;
end

MEMADR: begin

ALUSrcA <= ALU_SRC_A__RD1;
Expand All @@ -194,9 +220,10 @@ module ControlFSM(
ALUOp <= 2'b01;
ResultSrc <= RESULT_SRC__ALU_OUT;
Branch <= 1'b1;
pc_src <= zero_flag ? PC_SRC__JUMP : PC_SRC__INCREMENT;
PCUpdate <= 1'b1;

//pc_src <= zero_flag ? PC_SRC__JUMP : PC_SRC__INCREMENT;
//PCUpdate <= 1'b1;
pc_src <= PC_SRC__JUMP;
PCUpdate <= zero_flag;
end

ALUWB: begin
Expand Down
14 changes: 12 additions & 2 deletions src/Instruction_Decode/Instruction_Decode.v
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ module Instruction_Decode(

end

else begin // U-Type and J-Type
else begin // U-Type , J-Type, and Itype_jalr

funct3 = 3'b000;
funct7 = 7'b0;
Expand All @@ -56,6 +56,7 @@ module Instruction_Decode(
case (opcode)
RType: alu_op = ALU_OP__REGISTER_OPERATION;
IType_load: alu_op = ALU_OP__MEMORY_ACCESS;
IType_jalr: alu_op = ALU_OP__MEMORY_ACCESS; // rs1 + imm
SType: alu_op = ALU_OP__MEMORY_ACCESS;
BType: alu_op = ALU_OP__BRANCH;
UType_auipc: alu_op = ALU_OP__MEMORY_ACCESS; // used to add 0 to imm ext
Expand Down Expand Up @@ -101,6 +102,12 @@ module Instruction_Decode(

end

else if (opcode == IType_jalr) begin
rd = instr[11:7];
rs1 = instr[19:15];
rs2 = 5'b00000;
end

else if (opcode == UType_auipc || opcode == UType_lui) begin
rd = instr[11:7];
rs1 = 5'b00000;
Expand All @@ -123,11 +130,13 @@ module Instruction_Decode(
case(opcode)
IType_logic : imm_ext = {{20{instr[31]}}, instr[31:20]};
IType_load : imm_ext = {{20{instr[31]}}, instr[31:20]};
IType_jalr : imm_ext = {{20{instr[31]}}, instr[31:20]};
SType : imm_ext = {{20{instr[31]}}, instr[31:25], instr[11:7]};
BType : imm_ext = {{20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0};
JType : imm_ext = {{12{instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0};
UType_auipc : imm_ext = {instr[31:12], 12'b0};
UType_lui : imm_ext = {instr[31:12], 12'b0};


endcase
end
Expand All @@ -153,7 +162,8 @@ module Instruction_Decode(
.regWrite(reg_write),
.dataIn(ResultData),
.baseAddr(baseAddr),
.writeData(writeData)
.writeData(writeData),
.reset(reset)

);

Expand Down
7 changes: 5 additions & 2 deletions src/fetch.sv
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module fetch ( input wire clk
, input wire reset
, input wire cfsm__pc_update
, input pc_src_t cfsm__pc_src
, input addr_t alu_result_for_pc
, input wire cfsm__ir_write
, input imm_t imm_ext
, output addr_t pc_cur
Expand All @@ -22,8 +23,10 @@ module fetch ( input wire clk
always @ (*) begin
if (cfsm__pc_update) begin
case (cfsm__pc_src)
PC_SRC__INCREMENT: pc_next <= pc_cur + 32'h4;
PC_SRC__JUMP: pc_next <= pc_cur + imm_ext;
PC_SRC__INCREMENT: pc_next <= pc_cur + 32'h4;
PC_SRC__JUMP: pc_next <= pc_old + imm_ext;
//PC_SRC__JUMP: pc_next <= pc_cur + imm_ext;
PC_SRC__ALU_RESULT: pc_next <= {alu_result_for_pc[31:1], 1'b0};
endcase
end else begin
pc_next <= pc_cur;
Expand Down
1 change: 1 addition & 0 deletions src/params.vh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
parameter RType = 7'b0110011;
parameter IType_logic = 7'b0010011;
parameter IType_load = 7'b0000011;
parameter IType_jalr = 7'b1100111;
parameter SType = 7'b0100011;
parameter BType = 7'b1100011;
parameter JType = 7'b1101111;
Expand Down
1 change: 1 addition & 0 deletions src/top.v
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ module top ( input wire clk
, .reset ( reset )
, .cfsm__pc_update ( cfsm__pc_update )
, .cfsm__pc_src ( cfsm__pc_src )
, .alu_result_for_pc ( alu_out )
, .cfsm__ir_write ( cfsm__ir_write )
, .imm_ext ( imm_ext )

Expand Down
7 changes: 4 additions & 3 deletions src/types.svh
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,10 @@ typedef enum logic [1:0] {
RESULT_SRC__ALU_RESULT = 2'b10
} result_src_t;

typedef enum logic {
PC_SRC__INCREMENT = 1'b0,
PC_SRC__JUMP = 1'b1
typedef enum logic [1:0] {
PC_SRC__INCREMENT = 2'b00,
PC_SRC__JUMP = 2'b01,
PC_SRC__ALU_RESULT = 2'b10
} pc_src_t;

`endif
Binary file added test/.alu_branchifeq_tb.sv.swp
Binary file not shown.
72 changes: 72 additions & 0 deletions test/jal_tb.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
`timescale 1ns/1ps

`include "src/types.svh" // <-- bring in enum literals like PC_SRC__JUMP
`include "test/utils.svh"

module jal_only_tb;

reg clk;
reg reset;

// DUT
top uut
( .clk ( clk )
, .reset ( reset )
);

// 10ns clock
initial begin
clk = 0;
forever #5 clk = ~clk;
end

// helper: wait one cycle then assert expected FSM state
task wait_till_next_cfsm_state(input [3:0] expected_state);
@(posedge clk); #1;
`assert_equal(uut.control_fsm.current_state, expected_state)
endtask

initial begin
reset <= `TRUE;

// Program:
// 0x00000000: JAL x1, +16 (target = 16)
// J-type encoding: opcode=0x6F, rd=x1, imm=+16 -> 0x010000EF
uut.memory.M[0] = 32'h010000EF;

// Enter FETCH first (with reset asserted)
wait_till_next_cfsm_state(uut.control_fsm.FETCH);

// Release reset
reset <= `FALSE;

// -------- Single instruction: JAL x1, +16 --------

// DECODE: verify opcode, rd and immediate
wait_till_next_cfsm_state(uut.control_fsm.DECODE);
`assert_equal(uut.opcode, 7'b1101111) // JType (JAL)
`assert_equal(uut.instruction_decode.rd, 5'd1) // rd = x1
`assert_equal(uut.instruction_decode.imm_ext, 32'sd16) // imm = +16

// UNCONDJUMP: link = pc_old + 4, PC updates by pc + imm
wait_till_next_cfsm_state(uut.control_fsm.UNCONDJUMP);
`assert_equal(uut.alu.a, 32'd0) // pc_old at address 0
`assert_equal(uut.alu.b, 32'd4)
`assert_equal(uut.alu.out, 32'd4) // link value
`assert_equal(uut.cfsm__pc_update, 1'b1)
`assert_equal(uut.cfsm__pc_src, PC_SRC__JUMP) // <-- enum literal, no hierarchy

// ALUWB: write link back to rd (x1)
wait_till_next_cfsm_state(uut.control_fsm.ALUWB);

// Back to FETCH: PC should be 16; x1 should be 4
wait_till_next_cfsm_state(uut.control_fsm.FETCH);
`assert_equal(uut.instruction_decode.instanceRegFile.RFMem[1], 32'd4) // rd = link = 4
`assert_equal(uut.fetch.pc_cur, 32'd16) // PC jumped to 16

$finish;
end

`SETUP_VCD_DUMP(jal_only_tb)

endmodule
Loading
Loading