diff --git a/artiq/build_soc.py b/artiq/build_soc.py index e3a1f3360..bdf652948 100644 --- a/artiq/build_soc.py +++ b/artiq/build_soc.py @@ -2,6 +2,7 @@ import os import subprocess from migen import * +from migen.build.platforms.sinara import kasli from misoc.interconnect.csr import * from misoc.integration.builder import * @@ -57,11 +58,17 @@ def build_artiq_soc(soc, argdict): builder = Builder(soc, **argdict) builder.software_packages = [] builder.add_software_package("bootloader", os.path.join(firmware_dir, "bootloader")) + is_kasli_v1 = isinstance(soc.platform, kasli.Platform) and soc.platform.hw_rev in ("v1.0", "v1.1") if isinstance(soc, AMPSoC): - builder.add_software_package("libm") - builder.add_software_package("libprintf") - builder.add_software_package("libunwind") - builder.add_software_package("ksupport", os.path.join(firmware_dir, "ksupport")) + kernel_cpu_type = "vexriscv" if is_kasli_v1 else "vexriscv-g" + builder.add_software_package("libm", cpu_type=kernel_cpu_type) + builder.add_software_package("libprintf", cpu_type=kernel_cpu_type) + builder.add_software_package("libunwind", cpu_type=kernel_cpu_type) + builder.add_software_package("ksupport", os.path.join(firmware_dir, "ksupport"), cpu_type=kernel_cpu_type) + # Generate unwinder for soft float target (ARTIQ runtime) + # If the kernel lacks FPU, then the runtime unwinder is already generated + if not is_kasli_v1: + builder.add_software_package("libunwind") builder.add_software_package("runtime", os.path.join(firmware_dir, "runtime")) else: # Assume DRTIO satellite. diff --git a/artiq/coredevice/core.py b/artiq/coredevice/core.py index fa332858e..97cd9ed59 100644 --- a/artiq/coredevice/core.py +++ b/artiq/coredevice/core.py @@ -42,7 +42,7 @@ class Core: ref_multiplier: KernelInvariant[int32] coarse_ref_period: KernelInvariant[float] - def __init__(self, dmgr, host, ref_period, ref_multiplier=8, target="riscv"): + def __init__(self, dmgr, host, ref_period, ref_multiplier=8, target="rv32g"): self.ref_period = ref_period self.ref_multiplier = ref_multiplier self.coarse_ref_period = ref_period*ref_multiplier diff --git a/artiq/firmware/bootloader/Makefile b/artiq/firmware/bootloader/Makefile index 4dbd7b608..82baef3eb 100644 --- a/artiq/firmware/bootloader/Makefile +++ b/artiq/firmware/bootloader/Makefile @@ -11,7 +11,7 @@ all:: bootloader.bin $(RUSTOUT)/libbootloader.a: $(cargo) --target-dir ./cargo \ --manifest-path $(BOOTLOADER_DIRECTORY)/Cargo.toml \ - --target $(BOOTLOADER_DIRECTORY)/../riscv32ima-unknown-none-elf.json + --target $(BOOTLOADER_DIRECTORY)/../$(CARGO_TRIPLE).json bootloader.elf: $(RUSTOUT)/libbootloader.a $(link) -T $(BOOTLOADER_DIRECTORY)/bootloader.ld diff --git a/artiq/firmware/ksupport/Makefile b/artiq/firmware/ksupport/Makefile index f1fbfc19a..e1e3e48fd 100644 --- a/artiq/firmware/ksupport/Makefile +++ b/artiq/firmware/ksupport/Makefile @@ -22,11 +22,11 @@ all:: ksupport.elf $(RUSTOUT)/libksupport.a: $(cargo) --target-dir ./cargo \ --manifest-path $(KSUPPORT_DIRECTORY)/Cargo.toml \ - --target $(KSUPPORT_DIRECTORY)/../riscv32ima-unknown-none-elf.json + --target $(KSUPPORT_DIRECTORY)/../$(CARGO_TRIPLE).json ksupport.elf: $(RUSTOUT)/libksupport.a glue.o $(link) -T $(KSUPPORT_DIRECTORY)/ksupport.ld \ - -lunwind-elf -lprintf-float -lm + -lunwind-$(CPU)-elf -lprintf-float -lm %.o: $(KSUPPORT_DIRECTORY)/%.c $(compile) diff --git a/artiq/firmware/ksupport/rtio.rs b/artiq/firmware/ksupport/rtio.rs index 8736e33f5..d9f568f75 100644 --- a/artiq/firmware/ksupport/rtio.rs +++ b/artiq/firmware/ksupport/rtio.rs @@ -23,6 +23,8 @@ mod imp { pub const RTIO_I_STATUS_WAIT_STATUS: u8 = 4; pub const RTIO_I_STATUS_DESTINATION_UNREACHABLE: u8 = 8; + const OFFSET_MULTIPLE: isize = (csr::CONFIG_DATA_WIDTH_BYTES / 4) as isize; + pub extern fn init() { send(&RtioInitRequest); } @@ -47,14 +49,14 @@ mod imp { #[inline(always)] pub unsafe fn rtio_o_data_write(offset: usize, data: u32) { write_volatile( - csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1 - offset) as isize), + csr::rtio::O_DATA_ADDR.offset(OFFSET_MULTIPLE*(csr::rtio::O_DATA_SIZE - 1 - offset) as isize), data); } #[inline(always)] pub unsafe fn rtio_i_data_read(offset: usize) -> u32 { read_volatile( - csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1 - offset) as isize)) + csr::rtio::I_DATA_ADDR.offset(OFFSET_MULTIPLE*(csr::rtio::I_DATA_SIZE - 1 - offset) as isize)) } #[inline(never)] diff --git a/artiq/firmware/libboard_artiq/rpc_queue.rs b/artiq/firmware/libboard_artiq/rpc_queue.rs index 0e2049c81..877ed8c89 100644 --- a/artiq/firmware/libboard_artiq/rpc_queue.rs +++ b/artiq/firmware/libboard_artiq/rpc_queue.rs @@ -1,9 +1,9 @@ use core::ptr::{read_volatile, write_volatile}; use core::slice; -use board_misoc::{mem, cache}; +use board_misoc::{mem, cache, csr::CONFIG_DATA_WIDTH_BYTES}; -const SEND_MAILBOX: *mut usize = (mem::MAILBOX_BASE + 4) as *mut usize; -const RECV_MAILBOX: *mut usize = (mem::MAILBOX_BASE + 8) as *mut usize; +const SEND_MAILBOX: *mut usize = (mem::MAILBOX_BASE + CONFIG_DATA_WIDTH_BYTES as usize) as *mut usize; +const RECV_MAILBOX: *mut usize = (mem::MAILBOX_BASE + (CONFIG_DATA_WIDTH_BYTES * 2) as usize) as *mut usize; const QUEUE_BEGIN: usize = 0x44000000; const QUEUE_END: usize = 0x44ffff80; diff --git a/artiq/firmware/libboard_misoc/build.rs b/artiq/firmware/libboard_misoc/build.rs index 8160db88a..11d5aac2f 100644 --- a/artiq/firmware/libboard_misoc/build.rs +++ b/artiq/firmware/libboard_misoc/build.rs @@ -1,19 +1,16 @@ extern crate build_misoc; extern crate cc; -use std::env; use std::path::Path; fn main() { build_misoc::cfg(); - let triple = env::var("TARGET").unwrap(); - let arch = triple.split("-").next().unwrap(); - let vectors_path = Path::new(arch).join("vectors.S"); + let vectors_path = "riscv32/vectors.S"; - println!("cargo:rerun-if-changed={}", vectors_path.to_str().unwrap()); + println!("cargo:rerun-if-changed={}", vectors_path); cc::Build::new() .flag("--target=riscv32-unknown-elf") - .file(vectors_path) + .file(Path::new(vectors_path)) .compile("vectors"); } diff --git a/artiq/firmware/libboard_misoc/lib.rs b/artiq/firmware/libboard_misoc/lib.rs index 729f4d63b..3189ccfcd 100644 --- a/artiq/firmware/libboard_misoc/lib.rs +++ b/artiq/firmware/libboard_misoc/lib.rs @@ -8,7 +8,7 @@ extern crate log; extern crate smoltcp; #[cfg(target_arch = "riscv32")] -#[path = "riscv32ima/mod.rs"] +#[path = "riscv32/mod.rs"] mod arch; #[cfg(target_arch = "riscv32")] diff --git a/artiq/firmware/libboard_misoc/riscv32ima/boot.rs b/artiq/firmware/libboard_misoc/riscv32/boot.rs similarity index 100% rename from artiq/firmware/libboard_misoc/riscv32ima/boot.rs rename to artiq/firmware/libboard_misoc/riscv32/boot.rs diff --git a/artiq/firmware/libboard_misoc/riscv32ima/cache.rs b/artiq/firmware/libboard_misoc/riscv32/cache.rs similarity index 100% rename from artiq/firmware/libboard_misoc/riscv32ima/cache.rs rename to artiq/firmware/libboard_misoc/riscv32/cache.rs diff --git a/artiq/firmware/libboard_misoc/riscv32ima/mod.rs b/artiq/firmware/libboard_misoc/riscv32/mod.rs similarity index 100% rename from artiq/firmware/libboard_misoc/riscv32ima/mod.rs rename to artiq/firmware/libboard_misoc/riscv32/mod.rs diff --git a/artiq/firmware/libboard_misoc/riscv32ima/pmp.rs b/artiq/firmware/libboard_misoc/riscv32/pmp.rs similarity index 100% rename from artiq/firmware/libboard_misoc/riscv32ima/pmp.rs rename to artiq/firmware/libboard_misoc/riscv32/pmp.rs diff --git a/artiq/firmware/libboard_misoc/riscv32ima/vectors.S b/artiq/firmware/libboard_misoc/riscv32/vectors.S similarity index 100% rename from artiq/firmware/libboard_misoc/riscv32ima/vectors.S rename to artiq/firmware/libboard_misoc/riscv32/vectors.S diff --git a/artiq/firmware/libboard_misoc/sdram.rs b/artiq/firmware/libboard_misoc/sdram.rs index 61951e725..b3e112eb0 100644 --- a/artiq/firmware/libboard_misoc/sdram.rs +++ b/artiq/firmware/libboard_misoc/sdram.rs @@ -2,6 +2,7 @@ mod ddr { use core::{ptr, fmt}; use csr::{dfii, ddrphy}; + use csr::CONFIG_DATA_WIDTH_BYTES; use sdram_phy::{self, spin_cycles}; use sdram_phy::{DFII_COMMAND_CS, DFII_COMMAND_WE, DFII_COMMAND_CAS, DFII_COMMAND_RAS, DFII_COMMAND_WRDATA, DFII_COMMAND_RDDATA}; @@ -14,6 +15,8 @@ mod ddr { const DQS_SIGNAL_COUNT: usize = DFII_PIX_DATA_SIZE / 2; + const CSR_SEPARATION: isize = CONFIG_DATA_WIDTH_BYTES as isize / 4; + macro_rules! log { ($logger:expr, $( $arg:expr ),+) => ( if let &mut Some(ref mut f) = $logger { @@ -46,7 +49,7 @@ mod ddr { for n in 0..DQS_SIGNAL_COUNT { let dq_addr = dfii::PI0_RDDATA_ADDR - .offset((DQS_SIGNAL_COUNT - 1 - n) as isize); + .offset(CSR_SEPARATION * (DQS_SIGNAL_COUNT - 1 - n) as isize); log!(logger, "Module {}:\n", DQS_SIGNAL_COUNT - 1 - n); @@ -100,7 +103,7 @@ mod ddr { let mut failed = false; for n in 0..DQS_SIGNAL_COUNT { let dq_addr = dfii::PI0_RDDATA_ADDR - .offset((DQS_SIGNAL_COUNT - 1 - n) as isize); + .offset(CSR_SEPARATION * (DQS_SIGNAL_COUNT - 1 - n) as isize); delay[n] = 0; high_skew[n] = false; @@ -223,7 +226,7 @@ mod ddr { // Write test pattern for p in 0..DFII_NPHASES { for offset in 0..DFII_PIX_DATA_SIZE { - let addr = DFII_PIX_WRDATA_ADDR[p].offset(offset as isize); + let addr = DFII_PIX_WRDATA_ADDR[p].offset(CSR_SEPARATION * offset as isize); let data = prs[DFII_PIX_DATA_SIZE * p + offset]; ptr::write_volatile(addr, data as u32); } @@ -258,7 +261,7 @@ mod ddr { for p in 0..DFII_NPHASES { for &offset in [n, n + DQS_SIGNAL_COUNT].iter() { - let addr = DFII_PIX_RDDATA_ADDR[p].offset(offset as isize); + let addr = DFII_PIX_RDDATA_ADDR[p].offset(CSR_SEPARATION * offset as isize); let data = prs[DFII_PIX_DATA_SIZE * p + offset]; if ptr::read_volatile(addr) as u8 != data { working = false; @@ -306,7 +309,7 @@ mod ddr { // Write test pattern for p in 0..DFII_NPHASES { for offset in 0..DFII_PIX_DATA_SIZE { - let addr = DFII_PIX_WRDATA_ADDR[p].offset(offset as isize); + let addr = DFII_PIX_WRDATA_ADDR[p].offset(CSR_SEPARATION * offset as isize); let data = prs[DFII_PIX_DATA_SIZE * p + offset]; ptr::write_volatile(addr, data as u32); } @@ -349,7 +352,7 @@ mod ddr { for p in 0..DFII_NPHASES { for &offset in [n, n + DQS_SIGNAL_COUNT].iter() { - let addr = DFII_PIX_RDDATA_ADDR[p].offset(offset as isize); + let addr = DFII_PIX_RDDATA_ADDR[p].offset(CSR_SEPARATION * offset as isize); let data = prs[DFII_PIX_DATA_SIZE * p + offset]; if ptr::read_volatile(addr) as u8 != data { valid = false; diff --git a/artiq/firmware/libdyld/elf.rs b/artiq/firmware/libdyld/elf.rs index d8712b9fd..a10d9b4c3 100644 --- a/artiq/firmware/libdyld/elf.rs +++ b/artiq/firmware/libdyld/elf.rs @@ -2230,6 +2230,12 @@ pub const R_OR1K_TLS_TPOFF: u8 = 32; pub const R_OR1K_TLS_DTPOFF: u8 = 33; pub const R_OR1K_TLS_DTPMOD: u8 = 34; pub const R_OR1K_NUM: u8 = 35; +pub const EF_RISCV_RVC: u32 = 1; +pub const EF_RISCV_FLOAT_ABI: u32 = 6; +pub const EF_RISCV_FLOAT_ABI_SOFT: u32 = 0; +pub const EF_RISCV_FLOAT_ABI_SINGLE: u32 = 2; +pub const EF_RISCV_FLOAT_ABI_DOUBLE: u32 = 4; +pub const EF_RISCV_FLOAT_ABI_QUAD: u32 = 6; pub const R_RISCV_NONE: u8 = 0; pub const R_RISCV_32: u8 = 1; pub const R_RISCV_64: u8 = 2; diff --git a/artiq/firmware/libdyld/lib.rs b/artiq/firmware/libdyld/lib.rs index 1fec38959..1d89edaee 100644 --- a/artiq/firmware/libdyld/lib.rs +++ b/artiq/firmware/libdyld/lib.rs @@ -219,7 +219,13 @@ impl<'a> Library<'a> { #[cfg(not(target_arch = "riscv32"))] const ARCH: u16 = EM_NONE; - if ehdr.e_ident != IDENT || ehdr.e_type != ET_DYN || ehdr.e_machine != ARCH { + #[cfg(all(target_feature = "f", target_feature = "d"))] + const FLAGS: u32 = EF_RISCV_FLOAT_ABI_DOUBLE; + + #[cfg(not(all(target_feature = "f", target_feature = "d")))] + const FLAGS: u32 = EF_RISCV_FLOAT_ABI_SOFT; + + if ehdr.e_ident != IDENT || ehdr.e_type != ET_DYN || ehdr.e_machine != ARCH || ehdr.e_flags != FLAGS { return Err("not a shared library for current architecture")? } diff --git a/artiq/firmware/riscv32g-unknown-none-elf.json b/artiq/firmware/riscv32g-unknown-none-elf.json new file mode 100644 index 000000000..2a3fb8bfb --- /dev/null +++ b/artiq/firmware/riscv32g-unknown-none-elf.json @@ -0,0 +1,40 @@ +{ + "arch": "riscv32", + "code-model": "medium", + "cpu": "generic-rv32", + "crt-static-respected": true, + "data-layout": "e-m:e-p:32:32-i64:64-n32-S128", + "dynamic-linking": true, + "executables": true, + "features": "+m,+a,+f,+d", + "has-elf-tls": true, + "has-rpath": true, + "llvm-abiname": "ilp32d", + "llvm-target": "riscv32-unknown-linux", + "max-atomic-width": 32, + "position-independent-executables": true, + "pre-link-args": { + "gcc": [ + "-Wl,--as-needed", + "-Wl,-z,noexecstack" + ] + }, + "relro-level": "full", + "target-family": "unix", + "target-pointer-width": "32", + "unsupported-abis": [ + "cdecl", + "stdcall", + "fastcall", + "vectorcall", + "thiscall", + "aapcs", + "win64", + "sysv64", + "ptx-kernel", + "msp430-interrupt", + "x86-interrupt", + "amdgpu-kernel" + ] +} + \ No newline at end of file diff --git a/artiq/firmware/riscv32ima-unknown-none-elf.json b/artiq/firmware/riscv32ima-unknown-none-elf.json index ddacc0247..e41408842 100644 --- a/artiq/firmware/riscv32ima-unknown-none-elf.json +++ b/artiq/firmware/riscv32ima-unknown-none-elf.json @@ -1,32 +1,31 @@ { - "arch": "riscv32", - "cpu": "generic-rv32", - "data-layout": "e-m:e-p:32:32-i64:64-n32-S128", - "eh-frame-header": false, - "emit-debug-gdb-scripts": false, - "executables": true, - "features": "+m,+a,-c", - "is-builtin": false, - "linker": "rust-lld", - "linker-flavor": "ld.lld", - "llvm-target": "riscv32", - "max-atomic-width": 32, - "panic-strategy": "unwind", - "relocation-model": "static", - "target-pointer-width": "32", - "unsupported-abis": [ - "cdecl", - "stdcall", - "fastcall", - "vectorcall", - "thiscall", - "aapcs", - "win64", - "sysv64", - "ptx-kernel", - "msp430-interrupt", - "x86-interrupt", - "amdgpu-kernel" - ] - } - \ No newline at end of file + "arch": "riscv32", + "cpu": "generic-rv32", + "data-layout": "e-m:e-p:32:32-i64:64-n32-S128", + "eh-frame-header": false, + "emit-debug-gdb-scripts": false, + "executables": true, + "features": "+m,+a,-c", + "is-builtin": false, + "linker": "rust-lld", + "linker-flavor": "ld.lld", + "llvm-target": "riscv32", + "max-atomic-width": 32, + "panic-strategy": "unwind", + "relocation-model": "static", + "target-pointer-width": "32", + "unsupported-abis": [ + "cdecl", + "stdcall", + "fastcall", + "vectorcall", + "thiscall", + "aapcs", + "win64", + "sysv64", + "ptx-kernel", + "msp430-interrupt", + "x86-interrupt", + "amdgpu-kernel" + ] +} diff --git a/artiq/firmware/runtime/Makefile b/artiq/firmware/runtime/Makefile index 00506b2f3..3e4b91ba3 100644 --- a/artiq/firmware/runtime/Makefile +++ b/artiq/firmware/runtime/Makefile @@ -18,7 +18,7 @@ all:: runtime.bin runtime.fbi $(RUSTOUT)/libruntime.a: $(cargo) --target-dir ./cargo \ --manifest-path $(RUNTIME_DIRECTORY)/Cargo.toml \ - --target $(RUNTIME_DIRECTORY)/../riscv32ima-unknown-none-elf.json + --target $(RUNTIME_DIRECTORY)/../$(CARGO_TRIPLE).json runtime.elf: $(RUSTOUT)/libruntime.a ksupport_data.o $(link) -T $(RUNTIME_DIRECTORY)/runtime.ld \ diff --git a/artiq/firmware/satman/Makefile b/artiq/firmware/satman/Makefile index 7c3885c87..82e65d730 100644 --- a/artiq/firmware/satman/Makefile +++ b/artiq/firmware/satman/Makefile @@ -13,7 +13,7 @@ all:: satman.bin satman.fbi $(RUSTOUT)/libsatman.a: $(cargo) --target-dir ./cargo \ --manifest-path $(SATMAN_DIRECTORY)/Cargo.toml \ - --target $(SATMAN_DIRECTORY)/../riscv32ima-unknown-none-elf.json + --target $(SATMAN_DIRECTORY)/../$(CARGO_TRIPLE).json satman.elf: $(RUSTOUT)/libsatman.a $(link) -T $(SATMAN_DIRECTORY)/satman.ld diff --git a/artiq/frontend/artiq_ddb_template.py b/artiq/frontend/artiq_ddb_template.py index 4dfba4f93..52408a0d4 100755 --- a/artiq/frontend/artiq_ddb_template.py +++ b/artiq/frontend/artiq_ddb_template.py @@ -11,14 +11,16 @@ from artiq.coredevice import jsondesc def process_header(output, description): - if description["target"] not in ("kasli", "kasli_soc"): + if description["target"] == "kasli": + if description["hw_rev"] in ("v1.0", "v1.1"): + cpu_target = "rv32ima" + else: + cpu_target = "rv32g" + elif description["target"] == "kasli_soc": + cpu_target = "cortexa9" + else: raise NotImplementedError - cpu_target = { - "kasli": "riscv", - "kasli_soc": "cortexa9" - }[description["target"]] - print(textwrap.dedent(""" # Autogenerated for the {variant} variant core_addr = "{core_addr}" diff --git a/artiq/gateware/amp/kernel_cpu.py b/artiq/gateware/amp/kernel_cpu.py index a770b4326..6979b7b4f 100644 --- a/artiq/gateware/amp/kernel_cpu.py +++ b/artiq/gateware/amp/kernel_cpu.py @@ -1,4 +1,5 @@ from migen import * +from migen.build.platforms.sinara import kasli from misoc.interconnect.csr import * from misoc.interconnect import wishbone from misoc.cores import vexriscv @@ -14,21 +15,22 @@ class KernelCPU(Module): # # # - self._wb_slaves = WishboneSlaveManager(0x80000000) - # CPU core self.clock_domains.cd_sys_kernel = ClockDomain() self.comb += [ self.cd_sys_kernel.clk.eq(ClockSignal()), self.cd_sys_kernel.rst.eq(self._reset.storage) ] + kasli_v1 = isinstance(platform, kasli.Platform) and platform.hw_rev in ("v1.0", "v1.1") self.submodules.cpu = ClockDomainsRenamer("sys_kernel")( - vexriscv.VexRiscv( - platform, - exec_address)) + vexriscv.VexRiscv(platform, exec_address, + variant="VexRiscv_IMA" if kasli_v1 else "VexRiscv_G")) + + self.cpu_dw = len(self.cpu.dbus.dat_w) + self._wb_slaves = WishboneSlaveManager(0x80000000, dw=self.cpu_dw) # DRAM access - self.wb_sdram = wishbone.Interface() + self.wb_sdram = wishbone.Interface(data_width=self.cpu_dw, adr_width=32-log2_int(self.cpu_dw//8)) self.add_wb_slave(main_mem_origin, 0x10000000, self.wb_sdram) def get_csrs(self): @@ -37,7 +39,7 @@ class KernelCPU(Module): def do_finalize(self): self.submodules.wishbonecon = wishbone.InterconnectShared( [self.cpu.ibus, self.cpu.dbus], - self._wb_slaves.get_interconnect_slaves(), register=True) + self._wb_slaves.get_interconnect_slaves(), register=True, dw=self.cpu_dw) def add_wb_slave(self, origin, length, interface): if self.finalized: diff --git a/artiq/gateware/amp/mailbox.py b/artiq/gateware/amp/mailbox.py index 7c60056d1..6c498b821 100644 --- a/artiq/gateware/amp/mailbox.py +++ b/artiq/gateware/amp/mailbox.py @@ -3,9 +3,9 @@ from misoc.interconnect import wishbone class Mailbox(Module): - def __init__(self, size=1): - self.i1 = wishbone.Interface() - self.i2 = wishbone.Interface() + def __init__(self, size=1, adr_width=30): + self.i1 = wishbone.Interface(data_width=32, adr_width=adr_width) + self.i2 = wishbone.Interface(data_width=32, adr_width=adr_width) # # # diff --git a/artiq/gateware/amp/soc.py b/artiq/gateware/amp/soc.py index 76d79807c..91b75ca3a 100644 --- a/artiq/gateware/amp/soc.py +++ b/artiq/gateware/amp/soc.py @@ -1,3 +1,4 @@ +from migen import * from misoc.cores import timer from misoc.interconnect import wishbone @@ -19,21 +20,24 @@ class AMPSoC: self.csr_devices.append("kernel_cpu") mailbox_size = 3 - self.submodules.mailbox = Mailbox(mailbox_size) - self.add_wb_slave(self.mem_map["mailbox"], 4*mailbox_size, + self.csr_separation = self.kernel_cpu.cpu_dw//8 + + self.submodules.mailbox = Mailbox(mailbox_size, adr_width=32-log2_int(self.csr_separation)) + self.add_wb_slave(self.mem_map["mailbox"], self.csr_separation*mailbox_size, self.mailbox.i1) - self.kernel_cpu.add_wb_slave(self.mem_map["mailbox"], 4*mailbox_size, + self.kernel_cpu.add_wb_slave(self.mem_map["mailbox"], self.csr_separation*mailbox_size, self.mailbox.i2) self.add_memory_region("mailbox", self.mem_map["mailbox"] | 0x80000000, - 4*mailbox_size) + self.csr_separation*mailbox_size) def register_kernel_cpu_csrdevice(self, name, csrs=None): if csrs is None: csrs = getattr(self, name).get_csrs() - bank = wishbone.CSRBank(csrs) + csr_bus = wishbone.Interface(data_width=32, adr_width=32-log2_int(self.csr_separation)) + bank = wishbone.CSRBank(csrs, bus=csr_bus) self.submodules += bank - self.kernel_cpu.add_wb_slave(self.mem_map[name], 4*2**bank.decode_bits, bank.bus) + self.kernel_cpu.add_wb_slave(self.mem_map[name], self.csr_separation*2**bank.decode_bits, bank.bus) self.add_csr_region(name, self.mem_map[name] | 0x80000000, 32, csrs) diff --git a/artiq/gateware/drtio/aux_controller.py b/artiq/gateware/drtio/aux_controller.py index 8effda67d..051a03a20 100644 --- a/artiq/gateware/drtio/aux_controller.py +++ b/artiq/gateware/drtio/aux_controller.py @@ -212,14 +212,15 @@ class Receiver(Module, AutoCSR): # TODO: FullMemoryWE should be applied by migen.build @FullMemoryWE() class DRTIOAuxController(Module): - def __init__(self, link_layer): - self.bus = wishbone.Interface() + def __init__(self, link_layer, dw=32): + wsb = log2_int(dw//8) + + self.bus = wishbone.Interface(data_width=dw, adr_width=32-wsb) self.submodules.transmitter = Transmitter(link_layer, len(self.bus.dat_w)) self.submodules.receiver = Receiver(link_layer, len(self.bus.dat_w)) - tx_sdram_if = wishbone.SRAM(self.transmitter.mem, read_only=False) - rx_sdram_if = wishbone.SRAM(self.receiver.mem, read_only=True) - wsb = log2_int(len(self.bus.dat_w)//8) + tx_sdram_if = wishbone.SRAM(self.transmitter.mem, read_only=False, data_width=dw) + rx_sdram_if = wishbone.SRAM(self.receiver.mem, read_only=True, data_width=dw) decoder = wishbone.Decoder(self.bus, [(lambda a: a[log2_int(max_packet)-wsb] == 0, tx_sdram_if.bus), (lambda a: a[log2_int(max_packet)-wsb] == 1, rx_sdram_if.bus)], diff --git a/artiq/gateware/rtio/analyzer.py b/artiq/gateware/rtio/analyzer.py index 1818d3c43..ef154affa 100644 --- a/artiq/gateware/rtio/analyzer.py +++ b/artiq/gateware/rtio/analyzer.py @@ -3,6 +3,7 @@ from migen.genlib.record import Record, layout_len from misoc.interconnect.csr import * from misoc.interconnect import stream +from artiq.gateware.rtio import dma from artiq.gateware.rtio.cri import commands as cri_commands from artiq.coredevice.comm_analyzer import MessageType, ExceptionType @@ -42,20 +43,6 @@ assert layout_len(exception_layout) == message_len assert layout_len(stopped_layout) == message_len -def convert_signal(signal): - assert len(signal) % 8 == 0 - nbytes = len(signal)//8 - assert nbytes % 4 == 0 - nwords = nbytes//4 - signal_words = [] - for i in range(nwords): - signal_bytes = [] - for j in range(4): - signal_bytes.append(signal[8*(j+i*4):8*((j+i*4)+1)]) - signal_words.extend(reversed(signal_bytes)) - return Cat(*signal_words) - - class MessageEncoder(Module, AutoCSR): def __init__(self, tsc, cri, enable): self.source = stream.Endpoint([("data", message_len)]) @@ -150,7 +137,7 @@ class MessageEncoder(Module, AutoCSR): class DMAWriter(Module, AutoCSR): - def __init__(self, membus): + def __init__(self, membus, cpu_dw): aw = len(membus.adr) dw = len(membus.dat_w) messages_per_dw = dw//message_len @@ -175,7 +162,7 @@ class DMAWriter(Module, AutoCSR): membus.stb.eq(self.sink.stb), self.sink.ack.eq(membus.ack), membus.we.eq(1), - membus.dat_w.eq(convert_signal(self.sink.data)) + membus.dat_w.eq(dma.convert_signal(self.sink.data, cpu_dw//8)) ] if messages_per_dw > 1: for i in range(dw//8): @@ -207,7 +194,7 @@ class DMAWriter(Module, AutoCSR): class Analyzer(Module, AutoCSR): - def __init__(self, tsc, cri, membus, fifo_depth=128): + def __init__(self, tsc, cri, membus, fifo_depth=128, cpu_dw=32): # shutdown procedure: set enable to 0, wait until busy=0 self.enable = CSRStorage() self.busy = CSRStatus() @@ -219,7 +206,7 @@ class Analyzer(Module, AutoCSR): self.submodules.converter = stream.Converter( message_len, len(membus.dat_w), reverse=True, report_valid_token_count=True) - self.submodules.dma = DMAWriter(membus) + self.submodules.dma = DMAWriter(membus, cpu_dw) enable_r = Signal() self.sync += [ diff --git a/artiq/gateware/rtio/dma.py b/artiq/gateware/rtio/dma.py index 84f79dfa8..f81559dde 100644 --- a/artiq/gateware/rtio/dma.py +++ b/artiq/gateware/rtio/dma.py @@ -11,28 +11,20 @@ def _reverse_bytes(s, g): return Cat(reversed(list(s[i*g:(i+1)*g] for i in range(len(s)//g)))) -def reverse_bytes(s): - n = (len(s) + 7)//8 - return Cat(*[s[i*8:min((i + 1)*8, len(s))] - for i in reversed(range(n))]) - - -def convert_signal(signal): +def convert_signal(signal, granularity): assert len(signal) % 8 == 0 nbytes = len(signal)//8 - assert nbytes % 4 == 0 - nwords = nbytes//4 + assert nbytes % granularity == 0 + nwords = nbytes//granularity signal_words = [] for i in range(nwords): - signal_bytes = [] - for j in range(4): - signal_bytes.append(signal[8*(j+i*4):8*((j+i*4)+1)]) - signal_words.extend(reversed(signal_bytes)) - return Cat(*signal_words) + signal_words.append(_reverse_bytes( + signal[i*granularity*8:(i+1)*granularity*8], 8)) + return Cat(signal_words) class WishboneReader(Module): - def __init__(self, bus): + def __init__(self, bus, cpu_dw): self.bus = bus aw = len(bus.adr) @@ -57,18 +49,18 @@ class WishboneReader(Module): If(self.source.ack, data_reg_loaded.eq(0)), If(bus.ack, data_reg_loaded.eq(1), - self.source.data.eq(convert_signal(bus.dat_r)), + self.source.data.eq(convert_signal(bus.dat_r, cpu_dw//8)), self.source.eop.eq(self.sink.eop) ) ] class DMAReader(Module, AutoCSR): - def __init__(self, membus, enable): + def __init__(self, membus, enable, cpu_dw): aw = len(membus.adr) data_alignment = log2_int(len(membus.dat_w)//8) - self.submodules.wb_reader = WishboneReader(membus) + self.submodules.wb_reader = WishboneReader(membus, cpu_dw) self.source = self.wb_reader.source # All numbers in bytes @@ -344,11 +336,11 @@ class CRIMaster(Module, AutoCSR): class DMA(Module): - def __init__(self, membus): + def __init__(self, membus, cpu_dw): self.enable = CSR() flow_enable = Signal() - self.submodules.dma = DMAReader(membus, flow_enable) + self.submodules.dma = DMAReader(membus, flow_enable, cpu_dw) self.submodules.slicer = RecordSlicer(len(membus.dat_w)) self.submodules.time_offset = TimeOffset() self.submodules.cri_master = CRIMaster() diff --git a/artiq/gateware/targets/kasli.py b/artiq/gateware/targets/kasli.py index d47b583b1..311028fcb 100755 --- a/artiq/gateware/targets/kasli.py +++ b/artiq/gateware/targets/kasli.py @@ -104,9 +104,15 @@ class StandaloneBase(MiniSoC, AMPSoC): } mem_map.update(MiniSoC.mem_map) - def __init__(self, gateware_identifier_str=None, **kwargs): + def __init__(self, gateware_identifier_str=None, hw_rev="v2.0", **kwargs): + if hw_rev in ("v1.0", "v1.1"): + cpu_bus_width = 32 + else: + cpu_bus_width = 64 MiniSoC.__init__(self, cpu_type="vexriscv", + hw_rev=hw_rev, + cpu_bus_width=cpu_bus_width, sdram_controller_type="minicon", l2_size=128*1024, integrated_sram_size=8192, @@ -138,7 +144,7 @@ class StandaloneBase(MiniSoC, AMPSoC): self.csr_devices.append("rtio_core") self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc) self.submodules.rtio_dma = ClockDomainsRenamer("sys_kernel")( - rtio.DMA(self.get_native_sdram_if())) + rtio.DMA(self.get_native_sdram_if(), self.cpu_dw)) self.register_kernel_cpu_csrdevice("rtio") self.register_kernel_cpu_csrdevice("rtio_dma") self.submodules.cri_con = rtio.CRIInterconnectShared( @@ -156,7 +162,7 @@ class StandaloneBase(MiniSoC, AMPSoC): self.rtio_crg.cd_rtio.clk) self.submodules.rtio_analyzer = rtio.Analyzer(self.rtio_tsc, self.rtio_core.cri, - self.get_native_sdram_if()) + self.get_native_sdram_if(), cpu_dw=self.cpu_dw) self.csr_devices.append("rtio_analyzer") @@ -255,9 +261,15 @@ class MasterBase(MiniSoC, AMPSoC): } mem_map.update(MiniSoC.mem_map) - def __init__(self, rtio_clk_freq=125e6, enable_sata=False, gateware_identifier_str=None, **kwargs): + def __init__(self, rtio_clk_freq=125e6, enable_sata=False, gateware_identifier_str=None, hw_rev="v2.0", **kwargs): + if hw_rev in ("v1.0", "v1.1"): + cpu_bus_width = 32 + else: + cpu_bus_width = 64 MiniSoC.__init__(self, cpu_type="vexriscv", + hw_rev=hw_rev, + cpu_bus_width=cpu_bus_width, sdram_controller_type="minicon", l2_size=128*1024, integrated_sram_size=8192, @@ -333,7 +345,7 @@ class MasterBase(MiniSoC, AMPSoC): self.drtio_cri.append(core.cri) self.csr_devices.append(core_name) - coreaux = cdr(DRTIOAuxController(core.link_layer)) + coreaux = cdr(DRTIOAuxController(core.link_layer, self.cpu_dw)) setattr(self.submodules, coreaux_name, coreaux) self.csr_devices.append(coreaux_name) @@ -374,7 +386,7 @@ class MasterBase(MiniSoC, AMPSoC): self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc) self.submodules.rtio_dma = ClockDomainsRenamer("sys_kernel")( - rtio.DMA(self.get_native_sdram_if())) + rtio.DMA(self.get_native_sdram_if(), self.cpu_dw)) self.register_kernel_cpu_csrdevice("rtio") self.register_kernel_cpu_csrdevice("rtio_dma") self.submodules.cri_con = rtio.CRIInterconnectShared( @@ -386,7 +398,7 @@ class MasterBase(MiniSoC, AMPSoC): self.csr_devices.append("routing_table") self.submodules.rtio_analyzer = rtio.Analyzer(self.rtio_tsc, self.cri_con.switch.slave, - self.get_native_sdram_if()) + self.get_native_sdram_if(), cpu_dw=self.cpu_dw) self.csr_devices.append("rtio_analyzer") # Never running out of stupid features, GTs on A7 make you pack @@ -431,9 +443,15 @@ class SatelliteBase(BaseSoC): } mem_map.update(BaseSoC.mem_map) - def __init__(self, rtio_clk_freq=125e6, enable_sata=False, *, with_wrpll=False, gateware_identifier_str=None, **kwargs): + def __init__(self, rtio_clk_freq=125e6, enable_sata=False, *, with_wrpll=False, gateware_identifier_str=None, hw_rev="v2.0", **kwargs): + if hw_rev in ("v1.0", "v1.1"): + cpu_bus_width = 32 + else: + cpu_bus_width = 64 BaseSoC.__init__(self, cpu_type="vexriscv", + hw_rev=hw_rev, + cpu_bus_width=cpu_bus_width, sdram_controller_type="minicon", l2_size=128*1024, **kwargs) @@ -521,7 +539,7 @@ class SatelliteBase(BaseSoC): self.drtio_cri.append(core.cri) self.csr_devices.append(corerep_name) - coreaux = cdr(DRTIOAuxController(core.link_layer)) + coreaux = cdr(DRTIOAuxController(core.link_layer, self.cpu_dw)) setattr(self.submodules, coreaux_name, coreaux) self.csr_devices.append(coreaux_name) diff --git a/artiq/gateware/targets/kc705.py b/artiq/gateware/targets/kc705.py index 2a6e31d6f..4cec96e87 100755 --- a/artiq/gateware/targets/kc705.py +++ b/artiq/gateware/targets/kc705.py @@ -132,6 +132,7 @@ class _StandaloneBase(MiniSoC, AMPSoC): def __init__(self, gateware_identifier_str=None, **kwargs): MiniSoC.__init__(self, cpu_type="vexriscv", + cpu_bus_width=64, sdram_controller_type="minicon", l2_size=128*1024, integrated_sram_size=8192, @@ -176,7 +177,7 @@ class _StandaloneBase(MiniSoC, AMPSoC): self.csr_devices.append("rtio_core") self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc) self.submodules.rtio_dma = ClockDomainsRenamer("sys_kernel")( - rtio.DMA(self.get_native_sdram_if())) + rtio.DMA(self.get_native_sdram_if(), self.cpu_dw)) self.register_kernel_cpu_csrdevice("rtio") self.register_kernel_cpu_csrdevice("rtio_dma") self.submodules.cri_con = rtio.CRIInterconnectShared( @@ -192,7 +193,7 @@ class _StandaloneBase(MiniSoC, AMPSoC): self.rtio_crg.cd_rtio.clk) self.submodules.rtio_analyzer = rtio.Analyzer(self.rtio_tsc, self.rtio_core.cri, - self.get_native_sdram_if()) + self.get_native_sdram_if(), cpu_dw=self.cpu_dw) self.csr_devices.append("rtio_analyzer") @@ -209,6 +210,7 @@ class _MasterBase(MiniSoC, AMPSoC): def __init__(self, gateware_identifier_str=None, **kwargs): MiniSoC.__init__(self, cpu_type="vexriscv", + cpu_bus_width=64, sdram_controller_type="minicon", l2_size=128*1024, integrated_sram_size=8192, @@ -263,7 +265,7 @@ class _MasterBase(MiniSoC, AMPSoC): self.drtio_cri.append(core.cri) self.csr_devices.append(core_name) - coreaux = cdr(DRTIOAuxController(core.link_layer)) + coreaux = cdr(DRTIOAuxController(core.link_layer, self.cpu_dw)) setattr(self.submodules, coreaux_name, coreaux) self.csr_devices.append(coreaux_name) @@ -321,7 +323,7 @@ class _MasterBase(MiniSoC, AMPSoC): self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc) self.submodules.rtio_dma = ClockDomainsRenamer("sys_kernel")( - rtio.DMA(self.get_native_sdram_if())) + rtio.DMA(self.get_native_sdram_if(), self.cpu_dw)) self.register_kernel_cpu_csrdevice("rtio") self.register_kernel_cpu_csrdevice("rtio_dma") self.submodules.cri_con = rtio.CRIInterconnectShared( @@ -342,6 +344,7 @@ class _SatelliteBase(BaseSoC): def __init__(self, gateware_identifier_str=None, sma_as_sat=False, **kwargs): BaseSoC.__init__(self, cpu_type="vexriscv", + cpu_bus_width=64, sdram_controller_type="minicon", l2_size=128*1024, integrated_sram_size=8192, @@ -404,7 +407,7 @@ class _SatelliteBase(BaseSoC): self.drtio_cri.append(core.cri) self.csr_devices.append(corerep_name) - coreaux = cdr(DRTIOAuxController(core.link_layer)) + coreaux = cdr(DRTIOAuxController(core.link_layer, self.cpu_dw)) setattr(self.submodules, coreaux_name, coreaux) self.csr_devices.append(coreaux_name) diff --git a/artiq/gateware/targets/metlino.py b/artiq/gateware/targets/metlino.py index 74c2e35f0..ffb2b38b9 100755 --- a/artiq/gateware/targets/metlino.py +++ b/artiq/gateware/targets/metlino.py @@ -43,6 +43,7 @@ class Master(MiniSoC, AMPSoC): def __init__(self, gateware_identifier_str=None, **kwargs): MiniSoC.__init__(self, cpu_type="vexriscv", + cpu_bus_width=64, sdram_controller_type="minicon", l2_size=128*1024, integrated_sram_size=8192, @@ -96,7 +97,7 @@ class Master(MiniSoC, AMPSoC): drtio_cri.append(core.cri) self.csr_devices.append(core_name) - coreaux = cdr(DRTIOAuxController(core.link_layer)) + coreaux = cdr(DRTIOAuxController(core.link_layer, self.cpu_dw)) setattr(self.submodules, coreaux_name, coreaux) self.csr_devices.append(coreaux_name) @@ -149,7 +150,7 @@ class Master(MiniSoC, AMPSoC): self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc) self.submodules.rtio_dma = ClockDomainsRenamer("sys_kernel")( - rtio.DMA(self.get_native_sdram_if())) + rtio.DMA(self.get_native_sdram_if(), self.cpu_dw)) self.register_kernel_cpu_csrdevice("rtio") self.register_kernel_cpu_csrdevice("rtio_dma") self.submodules.cri_con = rtio.CRIInterconnectShared( diff --git a/artiq/gateware/targets/sayma_amc.py b/artiq/gateware/targets/sayma_amc.py index 6155eb31f..527d37b5c 100755 --- a/artiq/gateware/targets/sayma_amc.py +++ b/artiq/gateware/targets/sayma_amc.py @@ -57,6 +57,7 @@ class SatelliteBase(MiniSoC): def __init__(self, rtio_clk_freq=125e6, identifier_suffix="", gateware_identifier_str=None, with_sfp=False, *, with_wrpll, **kwargs): MiniSoC.__init__(self, cpu_type="vexriscv", + cpu_bus_width=64, sdram_controller_type="minicon", l2_size=128*1024, integrated_sram_size=8192, @@ -117,7 +118,7 @@ class SatelliteBase(MiniSoC): self.drtio_cri.append(core.cri) self.csr_devices.append(corerep_name) - coreaux = cdr(DRTIOAuxController(core.link_layer)) + coreaux = cdr(DRTIOAuxController(core.link_layer, self.cpu_dw)) setattr(self.submodules, coreaux_name, coreaux) self.csr_devices.append(coreaux_name) diff --git a/artiq/gateware/targets/sayma_rtm.py b/artiq/gateware/targets/sayma_rtm.py index 7fa740381..9d8a818b4 100755 --- a/artiq/gateware/targets/sayma_rtm.py +++ b/artiq/gateware/targets/sayma_rtm.py @@ -37,6 +37,7 @@ class _SatelliteBase(BaseSoC): def __init__(self, rtio_clk_freq, *, with_wrpll, gateware_identifier_str, **kwargs): BaseSoC.__init__(self, cpu_type="vexriscv", + cpu_bus_width=64, **kwargs) add_identifier(self, gateware_identifier_str=gateware_identifier_str) self.rtio_clk_freq = rtio_clk_freq @@ -79,7 +80,7 @@ class _SatelliteBase(BaseSoC): self.submodules.drtiosat = core self.csr_devices.append("drtiosat") - coreaux = cdr(DRTIOAuxController(core.link_layer)) + coreaux = cdr(DRTIOAuxController(core.link_layer, self.cpu_dw)) self.submodules.drtioaux0 = coreaux self.csr_devices.append("drtioaux0") diff --git a/artiq/gateware/test/drtio/test_aux_controller.py b/artiq/gateware/test/drtio/test_aux_controller.py index 64e2e15d7..68c9f3bbd 100644 --- a/artiq/gateware/test/drtio/test_aux_controller.py +++ b/artiq/gateware/test/drtio/test_aux_controller.py @@ -33,63 +33,67 @@ class Loopback(Module): class TB(Module): - def __init__(self, nwords): + def __init__(self, nwords, dw): self.submodules.link_layer = Loopback(nwords) self.submodules.aux_controller = ClockDomainsRenamer( - {"rtio": "sys", "rtio_rx": "sys"})(DRTIOAuxController(self.link_layer)) + {"rtio": "sys", "rtio_rx": "sys"})(DRTIOAuxController(self.link_layer, dw)) class TestAuxController(unittest.TestCase): def test_aux_controller(self): - dut = TB(4) + dut = { + 32: TB(4, 32), + 64: TB(4, 64) + } - def link_init(): + def link_init(dw): for i in range(8): yield - yield dut.link_layer.ready.eq(1) + yield dut[dw].link_layer.ready.eq(1) - def send_packet(packet): + def send_packet(packet, dw): for i, d in enumerate(packet): - yield from dut.aux_controller.bus.write(i, d) - yield from dut.aux_controller.transmitter.aux_tx_length.write(len(packet)*4) - yield from dut.aux_controller.transmitter.aux_tx.write(1) + yield from dut[dw].aux_controller.bus.write(i, d) + yield from dut[dw].aux_controller.transmitter.aux_tx_length.write(len(packet)*dw//8) + yield from dut[dw].aux_controller.transmitter.aux_tx.write(1) yield - while (yield from dut.aux_controller.transmitter.aux_tx.read()): + while (yield from dut[dw].aux_controller.transmitter.aux_tx.read()): yield - def receive_packet(): - while not (yield from dut.aux_controller.receiver.aux_rx_present.read()): + def receive_packet(dw): + while not (yield from dut[dw].aux_controller.receiver.aux_rx_present.read()): yield - length = yield from dut.aux_controller.receiver.aux_rx_length.read() + length = yield from dut[dw].aux_controller.receiver.aux_rx_length.read() r = [] - for i in range(length//4): - r.append((yield from dut.aux_controller.bus.read(256+i))) - yield from dut.aux_controller.receiver.aux_rx_present.write(1) + for i in range(length//(dw//8)): + r.append((yield from dut[dw].aux_controller.bus.read(256+i))) + yield from dut[dw].aux_controller.receiver.aux_rx_present.write(1) return r prng = random.Random(0) - def send_and_check_packet(): - data = [prng.randrange(2**32-1) for _ in range(prng.randrange(1, 16))] - yield from send_packet(data) - received = yield from receive_packet() + def send_and_check_packet(dw): + data = [prng.randrange(2**dw-1) for _ in range(prng.randrange(1, 16))] + yield from send_packet(data, dw) + received = yield from receive_packet(dw) self.assertEqual(data, received) - def sim(): - yield from link_init() + def sim(dw): + yield from link_init(dw) for i in range(8): - yield from send_and_check_packet() + yield from send_and_check_packet(dw) @passive - def rt_traffic(): + def rt_traffic(dw): while True: while prng.randrange(4): yield - yield dut.link_layer.tx_rt_frame.eq(1) + yield dut[dw].link_layer.tx_rt_frame.eq(1) yield while prng.randrange(4): yield - yield dut.link_layer.tx_rt_frame.eq(0) + yield dut[dw].link_layer.tx_rt_frame.eq(0) yield - run_simulation(dut, [sim(), rt_traffic()]) + run_simulation(dut[32], [sim(32), rt_traffic(32)]) + run_simulation(dut[64], [sim(64), rt_traffic(64)]) diff --git a/artiq/gateware/test/rtio/test_dma.py b/artiq/gateware/test/rtio/test_dma.py index 84bc4a3ff..c5d220a9f 100644 --- a/artiq/gateware/test/rtio/test_dma.py +++ b/artiq/gateware/test/rtio/test_dma.py @@ -31,24 +31,25 @@ def encode_record(channel, timestamp, address, data): return encode_n(len(r)+1, 1, 1) + r -def pack(x, size): +def pack(x, size, dw): r = [] for i in range((len(x)+size-1)//size): n = 0 - for j in range(i*size, (i+1)*size): - n <<= 8 + for j in range(i*size//(dw//8), (i+1)*size//(dw//8)): + n <<= dw try: - n |= x[j] + encoded = int.from_bytes(x[j*(dw//8): (j+1)*(dw//8)], "little") + n |= encoded except IndexError: pass r.append(n) return r -def encode_sequence(writes, ws): +def encode_sequence(writes, ws, dw): sequence = [b for write in writes for b in encode_record(*write)] sequence.append(0) - return pack(sequence, ws) + return pack(sequence, ws, dw) def do_dma(dut, address): @@ -84,9 +85,9 @@ prng = random.Random(0) class TB(Module): - def __init__(self, ws): - sequence1 = encode_sequence(test_writes1, ws) - sequence2 = encode_sequence(test_writes2, ws) + def __init__(self, ws, dw): + sequence1 = encode_sequence(test_writes1, ws, dw) + sequence2 = encode_sequence(test_writes2, ws, dw) offset = 512//ws assert len(sequence1) < offset sequence = ( @@ -97,7 +98,7 @@ class TB(Module): bus = wishbone.Interface(ws*8) self.submodules.memory = wishbone.SRAM( 1024, init=sequence, bus=bus) - self.submodules.dut = dma.DMA(bus) + self.submodules.dut = dma.DMA(bus, dw) test_writes_full_stack = [ @@ -109,7 +110,7 @@ test_writes_full_stack = [ class FullStackTB(Module): - def __init__(self, ws): + def __init__(self, ws, dw): self.ttl0 = Signal() self.ttl1 = Signal() @@ -121,12 +122,12 @@ class FullStackTB(Module): rtio.Channel.from_phy(self.phy1) ] - sequence = encode_sequence(test_writes_full_stack, ws) + sequence = encode_sequence(test_writes_full_stack, ws, dw) - bus = wishbone.Interface(ws*8) + bus = wishbone.Interface(ws*8, 32-log2_int(dw//8)) self.submodules.memory = wishbone.SRAM( 256, init=sequence, bus=bus) - self.submodules.dut = dma.DMA(bus) + self.submodules.dut = dma.DMA(bus, dw) self.submodules.tsc = rtio.TSC("async") self.submodules.rtio = rtio.Core(self.tsc, rtio_channels) self.comb += self.dut.cri.connect(self.rtio.cri) @@ -134,16 +135,22 @@ class FullStackTB(Module): class TestDMA(unittest.TestCase): def test_dma_noerror(self): - tb = TB(64) + tb = { + 32: TB(64, 32), + 64: TB(64, 64) + } - def do_writes(): - yield from do_dma(tb.dut, 0) - yield from do_dma(tb.dut, 512) + def do_writes(dw): + yield from do_dma(tb[dw].dut, 0) + yield from do_dma(tb[dw].dut, 512) - received = [] + received = { + 32: [], + 64: [] + } @passive - def rtio_sim(): - dut_cri = tb.dut.cri + def rtio_sim(dw): + dut_cri = tb[dw].dut.cri while True: cmd = yield dut_cri.cmd if cmd == cri.commands["nop"]: @@ -153,7 +160,7 @@ class TestDMA(unittest.TestCase): timestamp = yield dut_cri.o_timestamp address = yield dut_cri.o_address data = yield dut_cri.o_data - received.append((channel, timestamp, address, data)) + received[dw].append((channel, timestamp, address, data)) yield dut_cri.o_status.eq(1) for i in range(prng.randrange(10)): @@ -163,32 +170,46 @@ class TestDMA(unittest.TestCase): self.fail("unexpected RTIO command") yield - run_simulation(tb, [do_writes(), rtio_sim()]) - self.assertEqual(received, test_writes1 + test_writes2) + run_simulation(tb[32], [do_writes(32), rtio_sim(32)]) + self.assertEqual(received[32], test_writes1 + test_writes2) + + run_simulation(tb[64], [do_writes(64), rtio_sim(64)]) + self.assertEqual(received[64], test_writes1 + test_writes2) def test_full_stack(self): - tb = FullStackTB(64) + tb = { + 32: FullStackTB(64, 32), + 64: FullStackTB(64, 64) + } - ttl_changes = [] + ttl_changes = { + 32: [], + 64: [] + } @passive - def monitor(): + def monitor(dw): old_ttl_states = [0, 0] for time in itertools.count(): ttl_states = [ - (yield tb.ttl0), - (yield tb.ttl1) + (yield tb[dw].ttl0), + (yield tb[dw].ttl1) ] for i, (old, new) in enumerate(zip(old_ttl_states, ttl_states)): if new != old: - ttl_changes.append((time, i)) + ttl_changes[dw].append((time, i)) old_ttl_states = ttl_states yield - run_simulation(tb, {"sys": [ - do_dma(tb.dut, 0), monitor(), + run_simulation(tb[32], {"sys": [ + do_dma(tb[32].dut, 0), monitor(32), + (None for _ in range(70)), + ]}, {"sys": 8, "rsys": 8, "rtio": 8, "rio": 8, "rio_phy": 8}) + run_simulation(tb[64], {"sys": [ + do_dma(tb[64].dut, 0), monitor(64), (None for _ in range(70)), ]}, {"sys": 8, "rsys": 8, "rtio": 8, "rio": 8, "rio_phy": 8}) correct_changes = [(timestamp + 11, channel) for channel, timestamp, _, _ in test_writes_full_stack] - self.assertEqual(ttl_changes, correct_changes) + self.assertEqual(ttl_changes[32], correct_changes) + self.assertEqual(ttl_changes[64], correct_changes) diff --git a/flake.lock b/flake.lock index ce8d04b6a..6e78e6775 100644 --- a/flake.lock +++ b/flake.lock @@ -44,11 +44,11 @@ "src-migen": { "flake": false, "locked": { - "lastModified": 1634182166, - "narHash": "sha256-Iw2d8fCgwuuIevkugSqd8Iplj6N+2nR1pn+or5E38Fk=", + "lastModified": 1636715924, + "narHash": "sha256-V3ThFSo2d7OC4SHE0lCkKGQKeFXmvxtwZRWe5NMU3nM=", "owner": "m-labs", "repo": "migen", - "rev": "7507a2bb16dd2cac63535175ce67fb30dfdae1c0", + "rev": "9a0be7a4210ff96043412539eb5388659b81831d", "type": "github" }, "original": {