contributed by < jeremy90307
>
OS:ubuntu 22.04
sbt versopn:1.9.4
JDK version:1.8.0
Follow the instructions in Lab3: Construct a single-cycle RISC-V CPU with Chisel to set up the environment.
Install
gtkwave-3.3.117.tar.gz
.README
file instructions, if the installation fails, you need to install some packages.led
is an output terminal with an unsigned type and a bit width of 1.cntReg
is a counter with an initial value set to 0 and a bit width of 32 bitsCNT_MAX
is the maximum value of the counter.blkReg
represents the current state, with an initial value of 0 and a bit width of 1.when(...)
: When cntReg is equal to CNT_MAX, reset cntReg, and change the state of blkReg.blkReg
to the output signal.Install the dependent packages
Run all test
If the execution is successful, you will see the following message.
Run single Scala file for unit test
Output .vcd
file and analyze using GTKWave.
Pending resolution
My repository, where you can see the code for my completed MyCPU, is available here.
io.instruction_valid
is true, then jump to that location.(0x1000)io.instruction_valid
is false, then pc + 4From the diagram, it can be observed that when io.instruction_valid = 1
, the PC position returns to 0x1000 on the next rising edge of the clock.
After inputting 'sw,' 'lui,' and 'add,' the correct control signals are obtained.
io.memory_read_enable
is set to true.io.memory_write_enable
is set to true.input=0x00a02223L.U –> sw x10, 4(x0)
When the instruction is of the store type, io_memory_write_enable is set to 1.
muxLookup
description
funct3
: The value to be matched.
false.B
: The default value when no corresponding match is found.
InstructionsTypeB.beq -> (io.reg1_data === io.reg2_data),
:
If funct3 is equal to InstructionsTypeB.beq, then it evaluates whether io.reg1_data = io.reg2_data is true, and the result serves as the output of MuxLookup. If funct3 is not equal to InstructionsTypeB.beq, the default value for MuxLookup is set to false.B.
add
, and obtain the expected output.beq
, and determine the output address by comparing if they are equal.add
alu_io_op1
= io_reg1_data
= 016A05E2alu_io_op2
= io_reg2_data
= 0FBD8F12alu_io_result
is the sum of alu_io_op1
and alu_io_op2
.alu_io_function
is set to 1, it corresponds to ALUFunctions.add.add
operation matches the expectations.beq
alu_io_op1
= io_instruction_address
= 0x00000002alu_io_op2
= io_immediate
= 0x00000002alu_io_result
is the sum of alu_io_op1
and alu_io_op2
.alu_io_func=1
-> ALUFunctions.addreg1
and reg2
are the same, io_if_jump_flag
is set to 1.x0
always results in 0.io_write_enable
is set to 1, and data is written to registers_2, and it is successfully read.Complete CPU.scala
, this part is missing the necessary data and signals for connecting to module EXE.
hw2.S
) into the ca2023-lab/csrc
directory.ecall
and add _start:
Makefile
,and add hw2.asmbin
under BINS.$ make update
in the directory to generate hw2.asmbin
.CPUTest.scala
, add a Test class for hw2.asmbin
.Test the scale value for the first set of data in hw2.
Output
generate Verilog files
Parameter | Usage |
---|---|
-memory |
Specify the size of the simulation memory in words (4 bytes each). Example: -memory 4096 |
-instruction |
Specify the RISC-V program used to initialize the simulation memory. Example: -instruction src/main/resources/hello.asmbin |
-signature |
Specify the memory range and destination file to output after simulation. Example: -signature 0x100 0x200 mem.txt |
-halt |
Specify the halt identifier address; writing 0xBABECAFE to this memory address stops the simulation.Example: -halt 0x8000 |
-vcd |
Specify the filename for saving the simulation waveform during the process; not specifying this parameter will not generate a waveform file. Example: -vcd dump.vcd |
-time |
Specify the maximum simulation time; note that time is twice the number of cycles. Example: -time 1000 |
Load the hw2.asmbin
file, simulate for 2000 cycles, and save the simulation waveform to the dump01.vcd
file.
Output
dump01.vcd
to check its waveform.addi x2, x2, -4
Hexadecimal = 0xffc10113
Binary = 1111111 11100 00010 000 00010 0010011
io_instruction=0xFFC10113 -> addi x2, x2, -4
io_instruction_read_data=io_instruction
io_jump_flag_id=0
, the next pc is pc+4.io_ex_aluop1_source=0
reads the value of io_reg1_data
.io_ex_aluop2_source=1
,reads the value of io_ex_immediate
.(io_ex_immediate=0xFFFFFFFC = -4
)io_memory_read_enable=io_memory_write_enable=0
, there is no modification to the memoryio_memory_read_enable = 1
io_memory_write_enable = 1
io_regs_reg1_read_address=02
(x2=sp)alu_ctrl_io_alu_func=1
, it indicates the addi
function.io_aluop1_source=0
,alu_io_op1
is equal to io_reg1_data
, which is 0.io_aluop2_source=1
,alu_io_op2
is equal to io_immediate
, which is 0xFFFFFFFCio_alu_result
is equal to io_memory_bundle_address
, both being 0xFFFFFFFC.io_regs_write_data=0xFFFFFFFC
to register x2
.jal x0, 68
Hexdicimal:0x0440006f
Binary:00000100010000000000 00000 1101111
io_instruction[31:0]=0440006F -> jal x0, 68
io_instruction[31:0]=io_instruction_read_data[31:0]
io_jump_flag_id=1
is set to 1, the program counter (pc) consequently receives the instruction io_jump_address_id[31:0]=00001098
, resulting in the pc becoming pc=1098
.io_ex_aluop1_source=1
=io.instruction_address
io_ex_aluop2_source=1
reads the value of io_ex_immediate[31:0]=00000044
io_memory_read_enable=0
and io_memory_write_enable=0
, no read or write operations are performed on the memory.io_regs_reg1_read_address[4:0]=00
(x0) is equivalent to rd[4:0]=00
(x0).io_aluop1_source=1
,alu_io_op1
is equal to io_instruction_address=00001054
, where pc=1054.io_aluop2_source=1
, alu_io_op2 is equal
to io_immediate
, which is 0x00000044io_if_jump_flag=1
, the program counter (pc) jumps to io_if_jump_address=00001098
.(The next pc is set to 1098.)io_if_jump_address
is defined as the sum of io_immediate
and io_instruction_address
.io_alu_result
is equal to io_memory_bundle_address
.sw x15, 0(x12)
Hexadecimal=0x00f62023
Binary=00000000 11110 11000 100 00000 100011
io_instruction=0xFFC10113 -> sw x15, 0(x12)
io_instruction_read_data=io_instruction
io_jump_flag_id=0
, the next pc is pc+4.io_ex_aluop1_source=0
is the base memory address, which is the value of x12.(io_regs_reg1_read_address=0x0C
)io_ex_aluop2_source=1
is the offset of the memory address, which is 0.(io_ex_immediate=0x00000000
)io_memory_write_enable=1
, data is written into memory.alu_io_result=00001334
, is equal to the sum of ALU operands, where alu_io_op1=00001334
and alu_io_op2=00000000
.io_memory_bundle_address=0x00001334
, is equivalent to the ALU output, io_alu_result=00001334
.io_memory_bundle_write_data
is 0x00000000, which is equal to the value of io_reg2_data
.