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:
8
Makefile
8
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")"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# expected: dead0000, dead0001, 00000000
|
||||
# expected: ffffffffdead0000, ffffffffdead0001, 0000000000000000
|
||||
.text
|
||||
_start:
|
||||
lui x2, 0xdead0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# expected: dead0000, dead0001, fffff800, ffffffff, 00000000
|
||||
# expected: FFFFFFFFdead0000, FFFFFFFFdead0001, fffffffffffff800, ffffffffffffffff, 0000000000000000
|
||||
.text
|
||||
_start:
|
||||
lui x2, 0xdead0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# expected: FFFFFFFB, FFFFFFFB
|
||||
# expected: FFFFFFFFFFFFFFFB, FFFFFFFFFFFFFFFB
|
||||
.text
|
||||
_start:
|
||||
addi x1, x0, 0x0FB
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# expected: FFFFF1BC, FFFFF1BC
|
||||
# expected: FFFFFFFFFFFFF1BC, FFFFFFFFFFFFF1BC
|
||||
.text
|
||||
_start:
|
||||
lui x1, 0xF
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# expected: 00000000,FFFFF000,12345000
|
||||
# expected: 00000000,FFFFFFFFFFFFF000,12345000
|
||||
.text
|
||||
|
||||
lui x31, 0 #Test chargement d'une valeur nulle
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# expected: 000001FF, FFFFFFFF
|
||||
# expected: 000001FF, FFFFFFFFFFFFFFFF
|
||||
.text
|
||||
_start:
|
||||
addi x1, x0, 0x100
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# expected: 000001FF, FFFFFFFF
|
||||
# expected: 00000000000001FF, FFFFFFFFFFFFFFFF
|
||||
.text
|
||||
_start:
|
||||
addi x1, x0, 0x100
|
||||
|
||||
@@ -10,4 +10,5 @@ _start:
|
||||
sll x31, x1, x2
|
||||
|
||||
addi x1, x0, 0x0F0
|
||||
addi x2, x0, 63
|
||||
sll x31, x1, x2
|
||||
|
||||
@@ -8,4 +8,4 @@ _start:
|
||||
slli x31, x1, 31
|
||||
|
||||
addi x1, x0, 0x0F0
|
||||
slli x31, x1, 31
|
||||
slli x31, x1, 63
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# expected: 000000FF, FFFFFFFF, 00000000
|
||||
# expected: 000000FF, FFFFFFFFFFFFFFFF, 00000000
|
||||
.text
|
||||
_start:
|
||||
addi x1, x0, 0x3FC
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# expected: 000000FF, FFFFFFFF, 00000000
|
||||
# expected: 000000FF, FFFFFFFFFFFFFFFF, 00000000
|
||||
.text
|
||||
_start:
|
||||
addi x1, x0, 0x3FC
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
25
common/swap_endian.py
Normal 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)
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user