From 9daa296892d5e5548f3371d4bfca673898109433 Mon Sep 17 00:00:00 2001 From: Albin Chaboissier Date: Mon, 10 Nov 2025 16:38:40 +0100 Subject: [PATCH] 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 --- Makefile | 8 +- bench/tests/op/add.s | 2 +- bench/tests/op/addi.s | 2 +- bench/tests/op/lb.s | 2 +- bench/tests/op/lh.s | 2 +- bench/tests/op/lui.s | 2 +- bench/tests/op/or.s | 2 +- bench/tests/op/ori.s | 2 +- bench/tests/op/sll.s | 1 + bench/tests/op/slli.s | 2 +- bench/tests/op/sra.s | 2 +- bench/tests/op/srai.s | 2 +- bench/tests/op/srl.s | 2 +- bench/tests/op/srli.s | 3 +- bench/tests/op/sub.s | 2 +- common/swap_endian.py | 25 ++++++ src/main/scala/projet/Alu.scala | 18 ++--- src/main/scala/projet/BusInterconnect.scala | 10 +-- src/main/scala/projet/DMem.scala | 78 ++++++++++++++----- src/main/scala/projet/IDMem.scala | 36 ++++----- src/main/scala/projet/ImmediateDecoder.scala | 15 ++-- src/main/scala/projet/LedIp.scala | 4 +- src/main/scala/projet/RegFile.scala | 10 +-- .../scala/projet/{Rv32i.scala => Rv64i.scala} | 35 +++++++-- src/main/scala/projet/VgaIp.scala | 21 +++-- src/main/scala/projet/ZzTop.scala | 4 +- 26 files changed, 198 insertions(+), 94 deletions(-) create mode 100644 common/swap_endian.py rename src/main/scala/projet/{Rv32i.scala => Rv64i.scala} (82%) diff --git a/Makefile b/Makefile index 2e2037c..fa63653 100644 --- a/Makefile +++ b/Makefile @@ -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")" diff --git a/bench/tests/op/add.s b/bench/tests/op/add.s index 95a19b1..2a71bda 100644 --- a/bench/tests/op/add.s +++ b/bench/tests/op/add.s @@ -1,4 +1,4 @@ -# expected: dead0000, dead0001, 00000000 +# expected: ffffffffdead0000, ffffffffdead0001, 0000000000000000 .text _start: lui x2, 0xdead0 diff --git a/bench/tests/op/addi.s b/bench/tests/op/addi.s index bf10d14..a5ee7c1 100644 --- a/bench/tests/op/addi.s +++ b/bench/tests/op/addi.s @@ -1,4 +1,4 @@ -# expected: dead0000, dead0001, fffff800, ffffffff, 00000000 +# expected: FFFFFFFFdead0000, FFFFFFFFdead0001, fffffffffffff800, ffffffffffffffff, 0000000000000000 .text _start: lui x2, 0xdead0 diff --git a/bench/tests/op/lb.s b/bench/tests/op/lb.s index 8284a0e..b660ee0 100644 --- a/bench/tests/op/lb.s +++ b/bench/tests/op/lb.s @@ -1,4 +1,4 @@ -# expected: FFFFFFFB, FFFFFFFB +# expected: FFFFFFFFFFFFFFFB, FFFFFFFFFFFFFFFB .text _start: addi x1, x0, 0x0FB diff --git a/bench/tests/op/lh.s b/bench/tests/op/lh.s index 1ec4c7d..6d297a3 100644 --- a/bench/tests/op/lh.s +++ b/bench/tests/op/lh.s @@ -1,4 +1,4 @@ -# expected: FFFFF1BC, FFFFF1BC +# expected: FFFFFFFFFFFFF1BC, FFFFFFFFFFFFF1BC .text _start: lui x1, 0xF diff --git a/bench/tests/op/lui.s b/bench/tests/op/lui.s index 80caedc..b7101a6 100644 --- a/bench/tests/op/lui.s +++ b/bench/tests/op/lui.s @@ -1,4 +1,4 @@ -# expected: 00000000,FFFFF000,12345000 +# expected: 00000000,FFFFFFFFFFFFF000,12345000 .text lui x31, 0 #Test chargement d'une valeur nulle diff --git a/bench/tests/op/or.s b/bench/tests/op/or.s index 75c98ef..33aa4ce 100644 --- a/bench/tests/op/or.s +++ b/bench/tests/op/or.s @@ -1,4 +1,4 @@ -# expected: 000001FF, FFFFFFFF +# expected: 000001FF, FFFFFFFFFFFFFFFF .text _start: addi x1, x0, 0x100 diff --git a/bench/tests/op/ori.s b/bench/tests/op/ori.s index 81c5e08..eada614 100644 --- a/bench/tests/op/ori.s +++ b/bench/tests/op/ori.s @@ -1,4 +1,4 @@ -# expected: 000001FF, FFFFFFFF +# expected: 00000000000001FF, FFFFFFFFFFFFFFFF .text _start: addi x1, x0, 0x100 diff --git a/bench/tests/op/sll.s b/bench/tests/op/sll.s index 8027053..c5c2f98 100644 --- a/bench/tests/op/sll.s +++ b/bench/tests/op/sll.s @@ -10,4 +10,5 @@ _start: sll x31, x1, x2 addi x1, x0, 0x0F0 + addi x2, x0, 63 sll x31, x1, x2 diff --git a/bench/tests/op/slli.s b/bench/tests/op/slli.s index fdb2117..e25bd68 100644 --- a/bench/tests/op/slli.s +++ b/bench/tests/op/slli.s @@ -8,4 +8,4 @@ _start: slli x31, x1, 31 addi x1, x0, 0x0F0 - slli x31, x1, 31 + slli x31, x1, 63 diff --git a/bench/tests/op/sra.s b/bench/tests/op/sra.s index 3f7cc5c..7407863 100644 --- a/bench/tests/op/sra.s +++ b/bench/tests/op/sra.s @@ -1,4 +1,4 @@ -# expected: 000000FF, FFFFFFFF, 00000000 +# expected: 000000FF, FFFFFFFFFFFFFFFF, 00000000 .text _start: addi x1, x0, 0x3FC diff --git a/bench/tests/op/srai.s b/bench/tests/op/srai.s index 7289917..6923241 100644 --- a/bench/tests/op/srai.s +++ b/bench/tests/op/srai.s @@ -1,4 +1,4 @@ -# expected: 000000FF, FFFFFFFF, 00000000 +# expected: 000000FF, FFFFFFFFFFFFFFFF, 00000000 .text _start: addi x1, x0, 0x3FC diff --git a/bench/tests/op/srl.s b/bench/tests/op/srl.s index 6fed2c8..66b9ccf 100644 --- a/bench/tests/op/srl.s +++ b/bench/tests/op/srl.s @@ -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 diff --git a/bench/tests/op/srli.s b/bench/tests/op/srli.s index d9395a7..5bfb7be 100644 --- a/bench/tests/op/srli.s +++ b/bench/tests/op/srli.s @@ -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 diff --git a/bench/tests/op/sub.s b/bench/tests/op/sub.s index a70c142..15220da 100644 --- a/bench/tests/op/sub.s +++ b/bench/tests/op/sub.s @@ -1,4 +1,4 @@ -# expected: 00000000, 00000001, FFFFFFFF, 00000008 +# expected: 00000000, 00000001, FFFFFFFFFFFFFFFF, 00000008 .text _start: # Sub equal numbers diff --git a/common/swap_endian.py b/common/swap_endian.py new file mode 100644 index 0000000..06d1765 --- /dev/null +++ b/common/swap_endian.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +import sys + +if len(sys.argv) < 3: + print("Usage: swap_endian.py [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) diff --git a/src/main/scala/projet/Alu.scala b/src/main/scala/projet/Alu.scala index 1fb8327..2639ac4 100644 --- a/src/main/scala/projet/Alu.scala +++ b/src/main/scala/projet/Alu.scala @@ -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) { diff --git a/src/main/scala/projet/BusInterconnect.scala b/src/main/scala/projet/BusInterconnect.scala index 29c1120..df353d6 100644 --- a/src/main/scala/projet/BusInterconnect.scala +++ b/src/main/scala/projet/BusInterconnect.scala @@ -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, diff --git a/src/main/scala/projet/DMem.scala b/src/main/scala/projet/DMem.scala index 4924af0..4094238 100644 --- a/src/main/scala/projet/DMem.scala +++ b/src/main/scala/projet/DMem.scala @@ -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 } } diff --git a/src/main/scala/projet/IDMem.scala b/src/main/scala/projet/IDMem.scala index b5da30f..3b27647 100644 --- a/src/main/scala/projet/IDMem.scala +++ b/src/main/scala/projet/IDMem.scala @@ -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 diff --git a/src/main/scala/projet/ImmediateDecoder.scala b/src/main/scala/projet/ImmediateDecoder.scala index 6a31e4d..28e7a42 100644 --- a/src/main/scala/projet/ImmediateDecoder.scala +++ b/src/main/scala/projet/ImmediateDecoder.scala @@ -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) ) diff --git a/src/main/scala/projet/LedIp.scala b/src/main/scala/projet/LedIp.scala index 4c20227..09e6492 100644 --- a/src/main/scala/projet/LedIp.scala +++ b/src/main/scala/projet/LedIp.scala @@ -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 diff --git a/src/main/scala/projet/RegFile.scala b/src/main/scala/projet/RegFile.scala index 967b700..fa2910f 100644 --- a/src/main/scala/projet/RegFile.scala +++ b/src/main/scala/projet/RegFile.scala @@ -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) { diff --git a/src/main/scala/projet/Rv32i.scala b/src/main/scala/projet/Rv64i.scala similarity index 82% rename from src/main/scala/projet/Rv32i.scala rename to src/main/scala/projet/Rv64i.scala index 0f753f6..b6b8c6b 100644 --- a/src/main/scala/projet/Rv32i.scala +++ b/src/main/scala/projet/Rv64i.scala @@ -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 + ) } diff --git a/src/main/scala/projet/VgaIp.scala b/src/main/scala/projet/VgaIp.scala index d461dbe..33c284e 100644 --- a/src/main/scala/projet/VgaIp.scala +++ b/src/main/scala/projet/VgaIp.scala @@ -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)) } ) diff --git a/src/main/scala/projet/ZzTop.scala b/src/main/scala/projet/ZzTop.scala index aaa8207..1c730c4 100644 --- a/src/main/scala/projet/ZzTop.scala +++ b/src/main/scala/projet/ZzTop.scala @@ -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)