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-)
CC := $(PREFIX)gcc
OBJDUMP := $(PREFIX)objdump
OBJCOPY := $(PREFIX)objcopy
OBTOMEM := common/objtomem.awk
## 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)
ELFFLAGS :=$(ASFLAGS) $(MEM_DIR)/crt.o -Os -fno-unroll-loops
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)
$(CC) $(CFLAGS) -o $@ $<
$(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)
@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
_start:
lui x2, 0xdead0

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,4 +8,4 @@ _start:
slli x31, x1, 31
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
_start:
addi x1, x0, 0x3FC

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
# expected: 00000000, 00000001, FFFFFFFF, 00000008
# expected: 00000000, 00000001, FFFFFFFFFFFFFFFF, 00000008
.text
_start:
# 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
object AluOpCode extends ChiselEnum {
val Add, Sub, And, Or, Xor, ShiftLeft, ShiftRight, ShiftArithmeticRight,
LessThanSigned, LessThanUnsigned, GreaterEqualSigned,
GreaterEqualUnsigned, Equal = Value
val Add, AddW, Sub, And, Or, Xor, ShiftLeft, ShiftRight,
ShiftArithmeticRight, LessThanSigned, LessThanUnsigned,
GreaterEqualSigned, GreaterEqualUnsigned, Equal = Value
}
class Alu extends Module {
import AluOpCode._
val io = IO(new Bundle {
val a = Input(UInt(32.W))
val b = Input(UInt(32.W))
val out = Output(UInt(32.W))
val a = Input(UInt(64.W))
val b = Input(UInt(64.W))
val out = Output(UInt(64.W))
val opcode = Input(AluOpCode())
val comp_result = Output(Bool())
})
@@ -45,16 +45,16 @@ class Alu extends Module {
}
is(ShiftLeft) {
io.out := io.a << io.b(4, 0);
io.out := io.a << io.b(5, 0);
}
is(ShiftRight) {
io.out := io.a >> io.b(4, 0);
io.out := io.a >> io.b(5, 0);
}
is(ShiftArithmeticRight) {
// >> 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) {

View File

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

View File

@@ -7,7 +7,7 @@ import chisel3.util.Cat
import chisel3.util.Fill
object DMemSize extends ChiselEnum {
val Byte, Half, Word = Value
val Byte, Half, Word, Long = Value
}
class DMem extends Module {
@@ -17,64 +17,106 @@ class DMem extends Module {
val size = Input(DMemSize())
val en = Input(Bool())
val we = Input(Bool())
val addr = Input(UInt(32.W))
val data_in = Input(UInt(32.W))
val addr = Input(UInt(64.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())
})
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.data_out := 0.U
val bytes_enabled = VecInit(false.B, false.B, false.B, false.B)
val data = WireInit(0.U(32.W))
val bytes_enabled = VecInit(
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) {
switch(io.size) {
is(DMemSize.Byte) {
bytes_enabled(io.addr(1, 0)) := true.B
data := io.data_in << (io.addr(1) * 16.U + io.addr(0) * 8.U)
bytes_enabled(io.addr(2, 0)) := true.B
data := io.data_in <<
(io.addr(2) * 32.U + io.addr(1) * 16.U + io.addr(0) * 8.U)
}
is(DMemSize.Half) {
bytes_enabled((io.addr(1) * 2.U(2.W))(1, 0)) := true.B
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
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) {
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 :=
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 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);
when(Delay.Delay(io.en && !io.we, 1, false.B)) {
switch(Delay.Delay(io.size, 1, DMemSize.Byte)) {
is(DMemSize.Byte) {
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(
read_sign_extend,
Fill(24, dout(7)) << 8.U,
Fill(56, dout(7)) << 8.U,
0.U
);
}
is(DMemSize.Half) {
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(
read_sign_extend,
Fill(16, dout(15)) << 16.U,
Fill(48, dout(15)) << 16.U,
0.U
);
}
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
}
}

View File

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

View File

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

View File

@@ -7,14 +7,14 @@ import chisel3.util._
\*/
class LedIp extends Module {
val io = IO(new Bundle {
val x31 = Input(UInt(32.W))
val x31 = Input(UInt(64.W))
val switch = Input(UInt(4.W))
val led = Output(UInt(4.W))
val button = Input(UInt(3.W))
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 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 rs2_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 rs1_data = Output(UInt(32.W))
val rs2_data = Output(UInt(32.W))
val rs1_data = Output(UInt(64.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 regs = Mem(32, UInt(32.W))
val regs = Mem(32, UInt(64.W))
if (sim) {
when(reset.asBool) {

View File

@@ -2,15 +2,15 @@ package projet
import chisel3._
class Rv32i(sim: Boolean = true) extends Module {
class Rv64i(sim: Boolean = true) extends Module {
val io = IO(new Bundle {
val ibus = 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 reg_pc = RegInit(0.U(32.W));
val reg_pc = RegInit(0.U(64.W));
val reg_file = Module(new RegFile(sim));
reg_file.io.rd_data := 0.U;
@@ -44,7 +44,11 @@ class Rv32i(sim: Boolean = true) extends Module {
// Insert no-op if jump
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.op_type := control_unit.io.optype
@@ -88,9 +92,17 @@ class Rv32i(sim: Boolean = true) extends Module {
dmem.io.data_out
);
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 =
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
@@ -127,6 +139,15 @@ class Rv32i(sim: Boolean = true) extends Module {
dmem.io.addr := execute_out
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.vs := RegNext(sync.io.vsync)
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.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
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
io.bus.addr := addr(14, 0) ## 0.U(2.W)
io.bus.addr := addr(13, 0) ## 0.U(3.W)
val pixel = MuxCase(
0.U,
(0 until 4).map { i =>
(index === i.U) -> io.bus.rdata(8 * (3 - i) + 7, 8 * (3 - i))
(0 until 8).map { 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 push = Input(UInt(3.W))
// 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
// Port vga
@@ -36,7 +36,7 @@ class ZzTop(file: String = "", sim: Boolean = true) extends Module {
// Expose core for testing usage
withClockAndReset(clkg.io.clk_out1, rst) {
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 ldip = Module(new LedIp)
val clnt = Module(new CLint)