Lays groundword for Rv64i extension

Some base files had to be modified to support 64-bit architecture
as well as the Makefile to load 64-bit words into memory
This commit is contained in:
2025-11-10 16:38:40 +01:00
parent cbfd806444
commit 9daa296892
26 changed files with 198 additions and 94 deletions

View File

@@ -46,10 +46,11 @@ MEM_TESTS = $(addprefix test-, $(addprefix $(MEM_DIR)/, $(addsuffix .mem, $(base
PREFIX := $(shell command -v riscv64-unknown-elf-gcc >/dev/null 2>&1 && echo riscv64-unknown-elf- || echo /matieres/3MMFMN/riscv32/bin/riscv32-unknown-elf-) PREFIX := $(shell command -v riscv64-unknown-elf-gcc >/dev/null 2>&1 && echo riscv64-unknown-elf- || echo /matieres/3MMFMN/riscv32/bin/riscv32-unknown-elf-)
CC := $(PREFIX)gcc CC := $(PREFIX)gcc
OBJDUMP := $(PREFIX)objdump OBJDUMP := $(PREFIX)objdump
OBJCOPY := $(PREFIX)objcopy
OBTOMEM := common/objtomem.awk OBTOMEM := common/objtomem.awk
## Flags ## Flags
ASFLAGS :=-march=rv32i -mabi=ilp32 -ffreestanding -nostdlib -T $(BENCH_DIR)/link.ld ASFLAGS :=-march=rv64i -mabi=lp64 -ffreestanding -nostdlib -T $(BENCH_DIR)/link.ld
CFLAGS :=$(ASFLAGS) CFLAGS :=$(ASFLAGS)
ELFFLAGS :=$(ASFLAGS) $(MEM_DIR)/crt.o -Os -fno-unroll-loops ELFFLAGS :=$(ASFLAGS) $(MEM_DIR)/crt.o -Os -fno-unroll-loops
ODFLAGS :=-j .text -j .rodata -j .data -s ODFLAGS :=-j .text -j .rodata -j .data -s
@@ -70,7 +71,10 @@ $(MEM_DIR)/%.elf: $(BENCH_DIR)/%.c $(MEM_DIR)/crt.o |$(MEM_DIR)
$(MEM_DIR)/%.elf: $(BENCH_DIR)/%.s |$(MEM_DIR) $(MEM_DIR)/%.elf: $(BENCH_DIR)/%.s |$(MEM_DIR)
$(CC) $(CFLAGS) -o $@ $< $(CC) $(CFLAGS) -o $@ $<
$(MEM_DIR)/%.mem: $(MEM_DIR)/%.elf |$(MEM_DIR) $(MEM_DIR)/%.mem: $(MEM_DIR)/%.elf |$(MEM_DIR)
$(OBJDUMP) $(ODFLAGS) $< | awk -f $(OBTOMEM) | awk -f common/fix_mem.awk > $@ $(OBJCOPY) -O binary --verilog-data-width 8 $< $@.bin
python3 common/swap_endian.py $@.bin $@.bin.swapped 8
$(OBJCOPY) -I binary -O verilog --verilog-data-width 8 $@.bin.swapped $@
rm $@.bin $@.bin.swapped
test-$(MEM_DIR)/%.mem: $(MEM_DIR)/%.mem |$(MEM_DIR) test-$(MEM_DIR)/%.mem: $(MEM_DIR)/%.mem |$(MEM_DIR)
@PROG="$(shell echo $< | sed "s/^bench\/mem\///g" | sed "s/\.mem$$//g")" PROOT=$(shell pwd) ./mill TPchisel.test.testOnly $(TOP_REP).$(TOP_TEST) -- -z "$(shell echo $< | sed "s/^bench\/mem\///g" | sed "s/\.mem$$//g")" @PROG="$(shell echo $< | sed "s/^bench\/mem\///g" | sed "s/\.mem$$//g")" PROOT=$(shell pwd) ./mill TPchisel.test.testOnly $(TOP_REP).$(TOP_TEST) -- -z "$(shell echo $< | sed "s/^bench\/mem\///g" | sed "s/\.mem$$//g")"

View File

@@ -1,4 +1,4 @@
# expected: dead0000, dead0001, 00000000 # expected: ffffffffdead0000, ffffffffdead0001, 0000000000000000
.text .text
_start: _start:
lui x2, 0xdead0 lui x2, 0xdead0

View File

@@ -1,4 +1,4 @@
# expected: dead0000, dead0001, fffff800, ffffffff, 00000000 # expected: FFFFFFFFdead0000, FFFFFFFFdead0001, fffffffffffff800, ffffffffffffffff, 0000000000000000
.text .text
_start: _start:
lui x2, 0xdead0 lui x2, 0xdead0

View File

@@ -1,4 +1,4 @@
# expected: FFFFFFFB, FFFFFFFB # expected: FFFFFFFFFFFFFFFB, FFFFFFFFFFFFFFFB
.text .text
_start: _start:
addi x1, x0, 0x0FB addi x1, x0, 0x0FB

View File

@@ -1,4 +1,4 @@
# expected: FFFFF1BC, FFFFF1BC # expected: FFFFFFFFFFFFF1BC, FFFFFFFFFFFFF1BC
.text .text
_start: _start:
lui x1, 0xF lui x1, 0xF

View File

@@ -1,4 +1,4 @@
# expected: 00000000,FFFFF000,12345000 # expected: 00000000,FFFFFFFFFFFFF000,12345000
.text .text
lui x31, 0 #Test chargement d'une valeur nulle lui x31, 0 #Test chargement d'une valeur nulle

View File

@@ -1,4 +1,4 @@
# expected: 000001FF, FFFFFFFF # expected: 000001FF, FFFFFFFFFFFFFFFF
.text .text
_start: _start:
addi x1, x0, 0x100 addi x1, x0, 0x100

View File

@@ -1,4 +1,4 @@
# expected: 000001FF, FFFFFFFF # expected: 00000000000001FF, FFFFFFFFFFFFFFFF
.text .text
_start: _start:
addi x1, x0, 0x100 addi x1, x0, 0x100

View File

@@ -10,4 +10,5 @@ _start:
sll x31, x1, x2 sll x31, x1, x2
addi x1, x0, 0x0F0 addi x1, x0, 0x0F0
addi x2, x0, 63
sll x31, x1, x2 sll x31, x1, x2

View File

@@ -8,4 +8,4 @@ _start:
slli x31, x1, 31 slli x31, x1, 31
addi x1, x0, 0x0F0 addi x1, x0, 0x0F0
slli x31, x1, 31 slli x31, x1, 63

View File

@@ -1,4 +1,4 @@
# expected: 000000FF, FFFFFFFF, 00000000 # expected: 000000FF, FFFFFFFFFFFFFFFF, 00000000
.text .text
_start: _start:
addi x1, x0, 0x3FC addi x1, x0, 0x3FC

View File

@@ -1,4 +1,4 @@
# expected: 000000FF, FFFFFFFF, 00000000 # expected: 000000FF, FFFFFFFFFFFFFFFF, 00000000
.text .text
_start: _start:
addi x1, x0, 0x3FC addi x1, x0, 0x3FC

View File

@@ -5,7 +5,7 @@ _start:
addi x2, x0, 2 addi x2, x0, 2
srl x31, x1, x2 srl x31, x1, x2
lui x1, 0xA0000 li x1, 0x00000000A0000000
addi x2, x0, 31 addi x2, x0, 31
srl x31, x1, x2 srl x31, x1, x2

View File

@@ -4,7 +4,8 @@ _start:
addi x1, x0, 0x3FC addi x1, x0, 0x3FC
srli x31, x1, 2 srli x31, x1, 2
lui x1, 0xA0000 #lui x1, 0xA0000
li x1, 0x00000000A0000000
srli x31, x1, 31 srli x31, x1, 31
lui x1, 0x0A000 lui x1, 0x0A000

View File

@@ -1,4 +1,4 @@
# expected: 00000000, 00000001, FFFFFFFF, 00000008 # expected: 00000000, 00000001, FFFFFFFFFFFFFFFF, 00000008
.text .text
_start: _start:
# Sub equal numbers # Sub equal numbers

25
common/swap_endian.py Normal file
View File

@@ -0,0 +1,25 @@
#!/usr/bin/env python3
import sys
if len(sys.argv) < 3:
print("Usage: swap_endian.py <input> <output> [word_size]")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2]
word_size = int(sys.argv[3]) if len(sys.argv) > 3 else 4 # par défaut 32 bits
with open(input_file, "rb") as f:
data = f.read()
# Vérifie que la taille est multiple de la taille de mot
if len(data) % word_size != 0:
print("⚠️ Attention : la taille du fichier n'est pas multiple de la taille de mot")
swapped = bytearray()
for i in range(0, len(data), word_size):
word = data[i:i+word_size]
swapped.extend(word[::-1]) # inverse les octets dans chaque mot
with open(output_file, "wb") as f:
f.write(swapped)

View File

@@ -5,18 +5,18 @@ import chisel3.util.switch
import chisel3.util.is import chisel3.util.is
object AluOpCode extends ChiselEnum { object AluOpCode extends ChiselEnum {
val Add, Sub, And, Or, Xor, ShiftLeft, ShiftRight, ShiftArithmeticRight, val Add, AddW, Sub, And, Or, Xor, ShiftLeft, ShiftRight,
LessThanSigned, LessThanUnsigned, GreaterEqualSigned, ShiftArithmeticRight, LessThanSigned, LessThanUnsigned,
GreaterEqualUnsigned, Equal = Value GreaterEqualSigned, GreaterEqualUnsigned, Equal = Value
} }
class Alu extends Module { class Alu extends Module {
import AluOpCode._ import AluOpCode._
val io = IO(new Bundle { val io = IO(new Bundle {
val a = Input(UInt(32.W)) val a = Input(UInt(64.W))
val b = Input(UInt(32.W)) val b = Input(UInt(64.W))
val out = Output(UInt(32.W)) val out = Output(UInt(64.W))
val opcode = Input(AluOpCode()) val opcode = Input(AluOpCode())
val comp_result = Output(Bool()) val comp_result = Output(Bool())
}) })
@@ -45,16 +45,16 @@ class Alu extends Module {
} }
is(ShiftLeft) { is(ShiftLeft) {
io.out := io.a << io.b(4, 0); io.out := io.a << io.b(5, 0);
} }
is(ShiftRight) { is(ShiftRight) {
io.out := io.a >> io.b(4, 0); io.out := io.a >> io.b(5, 0);
} }
is(ShiftArithmeticRight) { is(ShiftArithmeticRight) {
// >> means arithmetic shift for SInts // >> means arithmetic shift for SInts
io.out := (io.a.asSInt >> io.b(4, 0)).asUInt; io.out := (io.a.asSInt >> io.b(5, 0)).asUInt;
} }
is(LessThanUnsigned) { is(LessThanUnsigned) {

View File

@@ -9,13 +9,13 @@ import chisel3.util._
// Signaux utilisés par le bus, coté esclave, on fait un // Signaux utilisés par le bus, coté esclave, on fait un
// Flip pour l'avoir coté maître ensuite // Flip pour l'avoir coté maître ensuite
class BusInterface extends Bundle { class BusInterface extends Bundle {
val addr = Input(UInt(32.W)) // adresse cible de la transaction val addr = Input(UInt(64.W)) // adresse cible de la transaction
val wdata = Input(UInt(32.W)) // donnée en écriture (max 32 bits) val wdata = Input(UInt(64.W)) // donnée en écriture (max 64 bits)
val rdata = Output( val rdata = Output(
UInt(32.W) UInt(64.W)
) // donnée lue de l'esclave, avec 1 cycle de retard ) // donnée lue de l'esclave, avec 1 cycle de retard
val be = Input( val be = Input(
Vec(4, Bool()) Vec(8, Bool())
) // byte-enable pour les accès écriture mémoire ) // byte-enable pour les accès écriture mémoire
val en = Input( val en = Input(
Bool() Bool()
@@ -85,7 +85,7 @@ class BusInterconnect extends Module {
val is_pvmem = RegNext(is_vmem) val is_pvmem = RegNext(is_vmem)
io.master.rdata := MuxCase( io.master.rdata := MuxCase(
0x0badaddL.U(32.W), 0x0badadd0badaddL.U(64.W),
Seq( Seq(
is_pdmem -> io.dmem.rdata, is_pdmem -> io.dmem.rdata,
is_pldip -> io.ldip.rdata, is_pldip -> io.ldip.rdata,

View File

@@ -7,7 +7,7 @@ import chisel3.util.Cat
import chisel3.util.Fill import chisel3.util.Fill
object DMemSize extends ChiselEnum { object DMemSize extends ChiselEnum {
val Byte, Half, Word = Value val Byte, Half, Word, Long = Value
} }
class DMem extends Module { class DMem extends Module {
@@ -17,64 +17,106 @@ class DMem extends Module {
val size = Input(DMemSize()) val size = Input(DMemSize())
val en = Input(Bool()) val en = Input(Bool())
val we = Input(Bool()) val we = Input(Bool())
val addr = Input(UInt(32.W)) val addr = Input(UInt(64.W))
val data_in = Input(UInt(32.W)) val data_in = Input(UInt(64.W))
val data_out = Output(UInt(32.W)) val data_out = Output(UInt(64.W))
val sign_extend = Input(Bool()) val sign_extend = Input(Bool())
}) })
io.dbus.addr := Cat(io.addr(31, 2), 0.U(2.W)); io.dbus.addr := Cat(io.addr(63, 3), 0.U(3.W));
io.dbus.en := io.en; io.dbus.en := io.en;
io.data_out := 0.U io.data_out := 0.U
val bytes_enabled = VecInit(false.B, false.B, false.B, false.B) val bytes_enabled = VecInit(
val data = WireInit(0.U(32.W)) false.B,
false.B,
false.B,
false.B,
false.B,
false.B,
false.B,
false.B
)
val data = WireInit(0.U(64.W))
when(io.we && io.en) { when(io.we && io.en) {
switch(io.size) { switch(io.size) {
is(DMemSize.Byte) { is(DMemSize.Byte) {
bytes_enabled(io.addr(1, 0)) := true.B bytes_enabled(io.addr(2, 0)) := true.B
data := io.data_in << (io.addr(1) * 16.U + io.addr(0) * 8.U) data := io.data_in <<
(io.addr(2) * 32.U + io.addr(1) * 16.U + io.addr(0) * 8.U)
} }
is(DMemSize.Half) { is(DMemSize.Half) {
bytes_enabled((io.addr(1) * 2.U(2.W))(1, 0)) := true.B
bytes_enabled( bytes_enabled(
(io.addr(1) * 2.U(2.W) + 1.U(2.W))(1, 0) (io.addr(2) * 4.U(3.W) + io.addr(1) * 2.U(3.W))(2, 0)
) := true.B ) := true.B
data := io.data_in << (io.addr(1) * 16.U) bytes_enabled(
(io.addr(2) * 4.U(3.W) + io.addr(1) * 2.U(3.W))(2, 0) + 1.U
) := true.B
data := io.data_in << (io.addr(2) * 32.U + io.addr(1) * 16.U)
} }
is(DMemSize.Word) { is(DMemSize.Word) {
bytes_enabled((io.addr(2) * 4.U(3.W))(2, 0)) := true.B
bytes_enabled((io.addr(2) * 4.U(3.W))(2, 0) + 1.U) := true.B
bytes_enabled((io.addr(2) * 4.U(3.W))(2, 0) + 2.U) := true.B
bytes_enabled((io.addr(2) * 4.U(3.W))(2, 0) + 3.U) := true.B
data := io.data_in << (io.addr(2) * 32.U)
}
is(DMemSize.Long) {
bytes_enabled := bytes_enabled :=
VecInit(true.B, true.B, true.B, true.B) VecInit(
true.B,
true.B,
true.B,
true.B,
true.B,
true.B,
true.B,
true.B
)
data := io.data_in data := io.data_in
} }
} }
} }
// Data out is available one cycle after the read request // Data out is available one cycle after the read request
val read_addr = Delay.Delay(io.addr, 1, 0.U); val read_addr = Delay.Delay(io.addr, 2, 0.U);
val read_sign_extend = Delay.Delay(io.sign_extend, 1, false.B); val read_sign_extend = Delay.Delay(io.sign_extend, 1, false.B);
when(Delay.Delay(io.en && !io.we, 1, false.B)) { when(Delay.Delay(io.en && !io.we, 1, false.B)) {
switch(Delay.Delay(io.size, 1, DMemSize.Byte)) { switch(Delay.Delay(io.size, 1, DMemSize.Byte)) {
is(DMemSize.Byte) { is(DMemSize.Byte) {
val dout = (io.dbus.rdata >> val dout = (io.dbus.rdata >>
(read_addr(1) * 16.U + read_addr(0) * 8.U)) & 0xff.U; (read_addr(2) * 32.U + read_addr(1) * 16.U + read_addr(
0
) * 8.U)) &
0xff.U;
io.data_out := dout | Mux( io.data_out := dout | Mux(
read_sign_extend, read_sign_extend,
Fill(24, dout(7)) << 8.U, Fill(56, dout(7)) << 8.U,
0.U 0.U
); );
} }
is(DMemSize.Half) { is(DMemSize.Half) {
val dout = (io.dbus.rdata >> val dout = (io.dbus.rdata >>
(read_addr(1) * 16.U)) & 0xffff.U; (read_addr(2) * 32.U + read_addr(1) * 16.U)) & 0xffff.U;
io.data_out := dout | Mux( io.data_out := dout | Mux(
read_sign_extend, read_sign_extend,
Fill(16, dout(15)) << 16.U, Fill(48, dout(15)) << 16.U,
0.U 0.U
); );
} }
is(DMemSize.Word) { is(DMemSize.Word) {
val dout = (io.dbus.rdata >>
(read_addr(2) * 32.U)) & 0xffffffffL.U;
io.data_out := dout | Mux(
read_sign_extend,
Fill(32, dout(31)) << 32.U,
0.U
);
}
is(DMemSize.Long) {
io.data_out := io.dbus.rdata io.data_out := io.dbus.rdata
} }
} }

View File

@@ -62,12 +62,12 @@ class xpm_memory_tdpram( // nom identique à celui de Xilinx
"MEMORY_INIT_FILE" -> StringParam(INIT_FILE), "MEMORY_INIT_FILE" -> StringParam(INIT_FILE),
"MEMORY_PRIMITIVE" -> "block", "MEMORY_PRIMITIVE" -> "block",
"MEMORY_SIZE" -> 524288, "MEMORY_SIZE" -> 524288,
"READ_DATA_WIDTH_A" -> 32, "READ_DATA_WIDTH_A" -> 64,
"READ_DATA_WIDTH_B" -> 32, "READ_DATA_WIDTH_B" -> 64,
"READ_LATENCY_A" -> 1, "READ_LATENCY_A" -> 1,
"READ_LATENCY_B" -> 1, "READ_LATENCY_B" -> 1,
"WRITE_DATA_WIDTH_A" -> 32, "WRITE_DATA_WIDTH_A" -> 64,
"WRITE_DATA_WIDTH_B" -> 32 "WRITE_DATA_WIDTH_B" -> 64
) )
) )
with HasBlackBoxResource { with HasBlackBoxResource {
@@ -77,12 +77,12 @@ class xpm_memory_tdpram( // nom identique à celui de Xilinx
val rsta = Input(Bool()) val rsta = Input(Bool())
val ena = Input(Bool()) val ena = Input(Bool())
val regcea = Input(Bool()) val regcea = Input(Bool())
val dina = Input(UInt(32.W)) val dina = Input(UInt(64.W))
val addra = Input(UInt(ADDR_WIDTH.W)) val addra = Input(UInt(ADDR_WIDTH.W))
val wea = Input(UInt(4.W)) val wea = Input(UInt(8.W))
val injectdbiterra = Input(Bool()) val injectdbiterra = Input(Bool())
val injectsbiterra = Input(Bool()) val injectsbiterra = Input(Bool())
val douta = Output(UInt(32.W)) val douta = Output(UInt(64.W))
// val dbiterrA = Output(Bool()) // val dbiterrA = Output(Bool())
// val sbiterrA = Output(Bool()) // val sbiterrA = Output(Bool())
// Port B // Port B
@@ -90,12 +90,12 @@ class xpm_memory_tdpram( // nom identique à celui de Xilinx
val rstb = Input(Bool()) val rstb = Input(Bool())
val enb = Input(Bool()) val enb = Input(Bool())
val regceb = Input(Bool()) val regceb = Input(Bool())
val dinb = Input(UInt(32.W)) val dinb = Input(UInt(64.W))
val addrb = Input(UInt(ADDR_WIDTH.W)) val addrb = Input(UInt(ADDR_WIDTH.W))
val web = Input(UInt(4.W)) val web = Input(UInt(8.W))
val injectdbiterrb = Input(Bool()) val injectdbiterrb = Input(Bool())
val injectsbiterrb = Input(Bool()) val injectsbiterrb = Input(Bool())
val doutb = Output(UInt(32.W)) val doutb = Output(UInt(64.W))
// val dbiterrB = Output(Bool()) // val dbiterrB = Output(Bool())
// val sbiterrB = Output(Bool()) // val sbiterrB = Output(Bool())
val sleep = Input(Bool()) val sleep = Input(Bool())
@@ -126,10 +126,10 @@ class IDMem(sim: Boolean, addrWidth: Int, memFile: String = "") extends Module {
val unifiedRam = Module( val unifiedRam = Module(
new dpram( new dpram(
NUM_COL = 4, NUM_COL = 8,
COL_WIDTH = 8, COL_WIDTH = 8,
ADDR_WIDTH = addrWidth - 2, ADDR_WIDTH = addrWidth - 3,
DATA_WIDTH = 32, DATA_WIDTH = 64,
INIT_FILE = memFile INIT_FILE = memFile
) )
) )
@@ -138,20 +138,20 @@ class IDMem(sim: Boolean, addrWidth: Int, memFile: String = "") extends Module {
unifiedRam.io.clkB := io.clkd unifiedRam.io.clkB := io.clkd
// instructions sur le port a // instructions sur le port a
unifiedRam.io.enaA := io.ibus.en unifiedRam.io.enaA := io.ibus.en
unifiedRam.io.addrA := io.ibus.addr(addrWidth - 1, 2) unifiedRam.io.addrA := io.ibus.addr(addrWidth - 1, 3)
io.ibus.rdata := unifiedRam.io.doutA io.ibus.rdata := unifiedRam.io.doutA
unifiedRam.io.weA := 0.U unifiedRam.io.weA := 0.U
unifiedRam.io.dinA := 0.U unifiedRam.io.dinA := 0.U
// données sur le port b // données sur le port b
unifiedRam.io.enaB := io.dbus.en unifiedRam.io.enaB := io.dbus.en
unifiedRam.io.addrB := io.dbus.addr(addrWidth - 1, 2) unifiedRam.io.addrB := io.dbus.addr(addrWidth - 1, 3)
io.dbus.rdata := unifiedRam.io.doutB io.dbus.rdata := unifiedRam.io.doutB
unifiedRam.io.weB := io.dbus.be.asUInt unifiedRam.io.weB := io.dbus.be.asUInt
unifiedRam.io.dinB := io.dbus.wdata unifiedRam.io.dinB := io.dbus.wdata
} else { } else {
val dpram = Module( val dpram = Module(
new xpm_memory_tdpram( new xpm_memory_tdpram(
ADDR_WIDTH = addrWidth - 2, ADDR_WIDTH = addrWidth - 3,
INIT_FILE = memFile INIT_FILE = memFile
) )
) )
@@ -160,7 +160,7 @@ class IDMem(sim: Boolean, addrWidth: Int, memFile: String = "") extends Module {
dpram.io.ena := io.dbus.en dpram.io.ena := io.dbus.en
dpram.io.regcea := false.B dpram.io.regcea := false.B
dpram.io.dina := io.dbus.wdata dpram.io.dina := io.dbus.wdata
dpram.io.addra := io.dbus.addr(addrWidth - 1, 2) dpram.io.addra := io.dbus.addr(addrWidth - 1, 3)
dpram.io.wea := io.dbus.be.asUInt dpram.io.wea := io.dbus.be.asUInt
dpram.io.injectdbiterra := false.B dpram.io.injectdbiterra := false.B
dpram.io.injectsbiterra := false.B dpram.io.injectsbiterra := false.B
@@ -171,7 +171,7 @@ class IDMem(sim: Boolean, addrWidth: Int, memFile: String = "") extends Module {
dpram.io.enb := io.ibus.en dpram.io.enb := io.ibus.en
dpram.io.regceb := false.B dpram.io.regceb := false.B
dpram.io.dinb := 0.U dpram.io.dinb := 0.U
dpram.io.addrb := io.ibus.addr(addrWidth - 1, 2) dpram.io.addrb := io.ibus.addr(addrWidth - 1, 3)
dpram.io.web := 0.U dpram.io.web := 0.U
dpram.io.injectdbiterrb := false.B dpram.io.injectdbiterrb := false.B
dpram.io.injectsbiterrb := false.B dpram.io.injectsbiterrb := false.B

View File

@@ -12,16 +12,17 @@ class ImmediateDecoder extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val op_type = Input(OpType()) val op_type = Input(OpType())
val instruction = Input(UInt(32.W)) val instruction = Input(UInt(32.W))
val immediate = Output(UInt(32.W)) val immediate = Output(UInt(64.W))
}) })
io.immediate := 0.U io.immediate := 0.U
// Decode and construct immediates // Decode and construct immediates
val imm_u = Cat(io.instruction(31, 12), 0.U(12.W)); val imm_u =
val imm_i = Cat(Fill(20, io.instruction(31)), io.instruction(31, 20)); Cat(Fill(32, io.instruction(31)), io.instruction(31, 12), 0.U(12.W));
val imm_ir = io.instruction(24, 20); val imm_i = Cat(Fill(52, io.instruction(31)), io.instruction(31, 20));
val imm_ir = io.instruction(25, 20);
val imm_j = Cat( val imm_j = Cat(
Fill(11, io.instruction(31)), Fill(33, io.instruction(31)),
io.instruction(31), io.instruction(31),
io.instruction(19, 12), io.instruction(19, 12),
io.instruction(20), io.instruction(20),
@@ -29,7 +30,7 @@ class ImmediateDecoder extends Module {
0.U 0.U
); );
val imm_b = Cat( val imm_b = Cat(
Fill(19, io.instruction(31)), Fill(51, io.instruction(31)),
io.instruction(31), io.instruction(31),
io.instruction(7), io.instruction(7),
io.instruction(30, 25), io.instruction(30, 25),
@@ -37,7 +38,7 @@ class ImmediateDecoder extends Module {
0.U 0.U
) )
val imm_s = Cat( val imm_s = Cat(
Fill(20, io.instruction(31)), Fill(52, io.instruction(31)),
io.instruction(31, 25), io.instruction(31, 25),
io.instruction(11, 7) io.instruction(11, 7)
) )

View File

@@ -7,14 +7,14 @@ import chisel3.util._
\*/ \*/
class LedIp extends Module { class LedIp extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val x31 = Input(UInt(32.W)) val x31 = Input(UInt(64.W))
val switch = Input(UInt(4.W)) val switch = Input(UInt(4.W))
val led = Output(UInt(4.W)) val led = Output(UInt(4.W))
val button = Input(UInt(3.W)) val button = Input(UInt(3.W))
val bus = new BusInterface val bus = new BusInterface
}) })
io.bus.rdata := 0x01ed01ed.U // On lira ça si on lit ! io.bus.rdata := 0x01ed01ed01ed01edL.U // On lira ça si on lit !
val dinReg = RegInit(0.U(32.W)) val dinReg = RegInit(0.U(32.W))
val x31Reg = RegNext(io.x31) // On lit x31 en continue val x31Reg = RegNext(io.x31) // On lit x31 en continue

View File

@@ -7,16 +7,16 @@ class RegFile(sim: Boolean = false) extends Module {
val rs1_addr = Input(UInt(5.W)) val rs1_addr = Input(UInt(5.W))
val rs2_addr = Input(UInt(5.W)) val rs2_addr = Input(UInt(5.W))
val rd_addr = Input(UInt(5.W)) val rd_addr = Input(UInt(5.W))
val rd_data = Input(UInt(32.W)) val rd_data = Input(UInt(64.W))
val we = Input(Bool()) val we = Input(Bool())
val rs1_data = Output(UInt(32.W)) val rs1_data = Output(UInt(64.W))
val rs2_data = Output(UInt(32.W)) val rs2_data = Output(UInt(64.W))
val x31 = Output(UInt(32.W)) val x31 = Output(UInt(64.W))
val valid_x31 = if (sim) Some(Output(Bool())) else None val valid_x31 = if (sim) Some(Output(Bool())) else None
}) })
val regs = Mem(32, UInt(32.W)) val regs = Mem(32, UInt(64.W))
if (sim) { if (sim) {
when(reset.asBool) { when(reset.asBool) {

View File

@@ -2,15 +2,15 @@ package projet
import chisel3._ import chisel3._
class Rv32i(sim: Boolean = true) extends Module { class Rv64i(sim: Boolean = true) extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ibus = Flipped(new BusInterface) val ibus = Flipped(new BusInterface)
val dbus = Flipped(new BusInterface) val dbus = Flipped(new BusInterface)
val x31 = Output(UInt(32.W)) val x31 = Output(UInt(64.W))
val valid_x31 = if (sim) Some(Output(Bool())) else None val valid_x31 = if (sim) Some(Output(Bool())) else None
}) })
val reg_pc = RegInit(0.U(32.W)); val reg_pc = RegInit(0.U(64.W));
val reg_file = Module(new RegFile(sim)); val reg_file = Module(new RegFile(sim));
reg_file.io.rd_data := 0.U; reg_file.io.rd_data := 0.U;
@@ -44,7 +44,11 @@ class Rv32i(sim: Boolean = true) extends Module {
// Insert no-op if jump // Insert no-op if jump
val instruction = val instruction =
Mux(is_jump, "b00000000000000000000000000010011".U, io.ibus.rdata); Mux(
is_jump,
"b00000000000000000000000000010011".U,
io.ibus.rdata >> (execute_pc(2) * 32.U)
);
immediate_decoder.io.instruction := instruction immediate_decoder.io.instruction := instruction
immediate_decoder.io.op_type := control_unit.io.optype immediate_decoder.io.op_type := control_unit.io.optype
@@ -88,9 +92,17 @@ class Rv32i(sim: Boolean = true) extends Module {
dmem.io.data_out dmem.io.data_out
); );
val rs1_data = val rs1_data =
Mux(rs1_index === reg_rd_index && rs1_index =/= 0.U, writeback_line, reg_file.io.rs1_data) Mux(
rs1_index === reg_rd_index && rs1_index =/= 0.U,
writeback_line,
reg_file.io.rs1_data
)
val rs2_data = val rs2_data =
Mux(rs2_index === reg_rd_index && rs2_index =/= 0.U, writeback_line, reg_file.io.rs2_data) Mux(
rs2_index === reg_rd_index && rs2_index =/= 0.U,
writeback_line,
reg_file.io.rs2_data
)
// EXECUTE // EXECUTE
@@ -127,6 +139,15 @@ class Rv32i(sim: Boolean = true) extends Module {
dmem.io.addr := execute_out dmem.io.addr := execute_out
io.ibus.wdata := 0.U; io.ibus.wdata := 0.U;
io.ibus.be := VecInit(false.B, false.B, false.B, false.B) io.ibus.be := VecInit(
false.B,
false.B,
false.B,
false.B,
false.B,
false.B,
false.B,
false.B
)
} }

View File

@@ -19,19 +19,28 @@ class VgaIp extends Module {
io.hs := RegNext(sync.io.hsync) io.hs := RegNext(sync.io.hsync)
io.vs := RegNext(sync.io.vsync) io.vs := RegNext(sync.io.vsync)
val img_sync = RegNext(sync.io.img) val img_sync = RegNext(sync.io.img)
val index = RegNext(sync.io.x(2, 1)) val index = RegNext(sync.io.x(3, 1))
io.bus.en := true.B io.bus.en := true.B
io.bus.be := VecInit(false.B, false.B, false.B, false.B) io.bus.be := VecInit(
false.B,
false.B,
false.B,
false.B,
false.B,
false.B,
false.B,
false.B
)
io.bus.wdata := 0.U io.bus.wdata := 0.U
val addr = 80.U * sync.io.y(8, 1) + sync.io.x(9, 3) val addr = 40.U * sync.io.y(8, 1) + sync.io.x(9, 4)
// Adresse mot dans la ram vidéo // Adresse mot dans la ram vidéo
io.bus.addr := addr(14, 0) ## 0.U(2.W) io.bus.addr := addr(13, 0) ## 0.U(3.W)
val pixel = MuxCase( val pixel = MuxCase(
0.U, 0.U,
(0 until 4).map { i => (0 until 8).map { i =>
(index === i.U) -> io.bus.rdata(8 * (3 - i) + 7, 8 * (3 - i)) (index === i.U) -> io.bus.rdata(8 * (7 - i) + 7, 8 * (7 - i))
} }
) )

View File

@@ -9,7 +9,7 @@ class ZzTop(file: String = "", sim: Boolean = true) extends Module {
val led = Output(UInt(4.W)) val led = Output(UInt(4.W))
val push = Input(UInt(3.W)) val push = Input(UInt(3.W))
// Debug simu pour ne pas s'embeter avec le switch dans le testbench // Debug simu pour ne pas s'embeter avec le switch dans le testbench
val x31 = if (sim) Some(Output(UInt(32.W))) else None val x31 = if (sim) Some(Output(UInt(64.W))) else None
val valid_x31 = if (sim) Some(Output(Bool())) else None val valid_x31 = if (sim) Some(Output(Bool())) else None
// Port vga // Port vga
@@ -36,7 +36,7 @@ class ZzTop(file: String = "", sim: Boolean = true) extends Module {
// Expose core for testing usage // Expose core for testing usage
withClockAndReset(clkg.io.clk_out1, rst) { withClockAndReset(clkg.io.clk_out1, rst) {
val interconnect = Module(new BusInterconnect) val interconnect = Module(new BusInterconnect)
val core = Module(new Rv32i(sim)) val core = Module(new Rv64i(sim))
val dmem = Module(new IDMem(sim, 16, file)) val dmem = Module(new IDMem(sim, 16, file))
val ldip = Module(new LedIp) val ldip = Module(new LedIp)
val clnt = Module(new CLint) val clnt = Module(new CLint)