From 054b79c571ba277086a454cca203bfcb71cfdc26 Mon Sep 17 00:00:00 2001 From: Alexander Williams Date: Tue, 3 Dec 2024 19:32:30 -0800 Subject: [PATCH] [prim,earlgrey,fpga] Add specialized ram_1p prim Add a specialized ram_1p prim for the prim_xilinx library. This prim adds some prim_xilinx-specific parameters to enable selecting particular layouts for embedded memories. The intention is to have the top-level override the parameters with hierarchical assignment. This feature is intended for use with memories that are too wide to fit in updatemem's capabilities (where splicing is required). The flash info pages are one such type, since updatemem can only handle up to 64-bit wide items, and the info page array is 76 bits wide. Synthesis chooses the most efficient layout of the memories, but the layout is awkward for handling splices. Force earlgrey's flash info data and metadata into separate arrays for the FPGA. Signed-off-by: Alexander Williams --- hw/ip/prim_xilinx/lint/prim_xilinx_ram_1p.vlt | 1 + .../lint/prim_xilinx_ram_1p.waiver | 1 + .../prim_xilinx/prim_xilinx_default_pkg.core | 19 ++ hw/ip/prim_xilinx/prim_xilinx_ram_1p.core | 47 +++++ hw/ip/prim_xilinx/rtl/prim_xilinx_pkg.sv | 11 ++ hw/ip/prim_xilinx/rtl/prim_xilinx_ram_1p.sv | 77 ++++++++ hw/ip/prim_xilinx/rtl/prim_xilinx_rom.sv | 52 ++++++ .../prim_xilinx_ultrascale_ram_1p.core | 19 ++ .../rtl/prim_xilinx_ultrascale_ram_1p.sv | 30 +++ hw/top_earlgrey/chip_earlgrey_cw310.core | 2 +- .../chip_earlgrey_cw310_hyperdebug.core | 2 +- hw/top_earlgrey/chip_earlgrey_cw340.core | 2 +- hw/top_earlgrey/data/synth.xdc | 14 -- hw/top_earlgrey/earlgrey_xilinx_prim_pkg.core | 19 ++ hw/top_earlgrey/rtl/prim_xilinx_pkg.sv | 14 ++ .../util/vivado_hook_write_bitstream_pre.tcl | 175 +++++++++++++----- .../chip_englishbreakfast_cw305.core | 1 + 17 files changed, 422 insertions(+), 64 deletions(-) create mode 100644 hw/ip/prim_xilinx/lint/prim_xilinx_ram_1p.vlt create mode 100644 hw/ip/prim_xilinx/lint/prim_xilinx_ram_1p.waiver create mode 100644 hw/ip/prim_xilinx/prim_xilinx_default_pkg.core create mode 100644 hw/ip/prim_xilinx/prim_xilinx_ram_1p.core create mode 100644 hw/ip/prim_xilinx/rtl/prim_xilinx_pkg.sv create mode 100644 hw/ip/prim_xilinx/rtl/prim_xilinx_ram_1p.sv create mode 100644 hw/ip/prim_xilinx/rtl/prim_xilinx_rom.sv create mode 100644 hw/ip/prim_xilinx_ultrascale/prim_xilinx_ultrascale_ram_1p.core create mode 100644 hw/ip/prim_xilinx_ultrascale/rtl/prim_xilinx_ultrascale_ram_1p.sv delete mode 100644 hw/top_earlgrey/data/synth.xdc create mode 100644 hw/top_earlgrey/earlgrey_xilinx_prim_pkg.core create mode 100644 hw/top_earlgrey/rtl/prim_xilinx_pkg.sv diff --git a/hw/ip/prim_xilinx/lint/prim_xilinx_ram_1p.vlt b/hw/ip/prim_xilinx/lint/prim_xilinx_ram_1p.vlt new file mode 100644 index 00000000000000..8b137891791fe9 --- /dev/null +++ b/hw/ip/prim_xilinx/lint/prim_xilinx_ram_1p.vlt @@ -0,0 +1 @@ + diff --git a/hw/ip/prim_xilinx/lint/prim_xilinx_ram_1p.waiver b/hw/ip/prim_xilinx/lint/prim_xilinx_ram_1p.waiver new file mode 100644 index 00000000000000..8b137891791fe9 --- /dev/null +++ b/hw/ip/prim_xilinx/lint/prim_xilinx_ram_1p.waiver @@ -0,0 +1 @@ + diff --git a/hw/ip/prim_xilinx/prim_xilinx_default_pkg.core b/hw/ip/prim_xilinx/prim_xilinx_default_pkg.core new file mode 100644 index 00000000000000..efcff71f05a703 --- /dev/null +++ b/hw/ip/prim_xilinx/prim_xilinx_default_pkg.core @@ -0,0 +1,19 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim_xilinx:prim_xilinx_default_pkg" +description: "Single port RAM" +virtual: + - lowrisc:prim_xilinx:prim_xilinx_pkg +filesets: + files_rtl: + files: + - rtl/prim_xilinx_pkg.sv + file_type: systemVerilogSource + +targets: + default: &default_target + filesets: + - files_rtl diff --git a/hw/ip/prim_xilinx/prim_xilinx_ram_1p.core b/hw/ip/prim_xilinx/prim_xilinx_ram_1p.core new file mode 100644 index 00000000000000..065fabf53164a2 --- /dev/null +++ b/hw/ip/prim_xilinx/prim_xilinx_ram_1p.core @@ -0,0 +1,47 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim_xilinx:ram_1p" +description: "Single port RAM" +filesets: + files_rtl: + depend: + - lowrisc:prim:assert + - lowrisc:prim:ram_1p_pkg + - lowrisc:prim_xilinx:prim_xilinx_pkg + - lowrisc:prim_generic:ram_1p + - lowrisc:prim:util_memload + files: + - rtl/prim_xilinx_ram_1p.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + files: + - lint/prim_xilinx_ram_1p.vlt + file_type: vlt + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + files: + - lint/prim_xilinx_ram_1p.waiver + file_type: waiver + + files_veriblelint_waiver: + depend: + # common waivers + - lowrisc:lint:common + +targets: + default: + filesets: + - tool_verilator ? (files_verilator_waiver) + - tool_ascentlint ? (files_ascentlint_waiver) + - tool_veriblelint ? (files_veriblelint_waiver) + - files_rtl diff --git a/hw/ip/prim_xilinx/rtl/prim_xilinx_pkg.sv b/hw/ip/prim_xilinx/rtl/prim_xilinx_pkg.sv new file mode 100644 index 00000000000000..3c3346c30752cd --- /dev/null +++ b/hw/ip/prim_xilinx/rtl/prim_xilinx_pkg.sv @@ -0,0 +1,11 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package prim_xilinx_pkg; + + function int get_ram_max_width(int width, int depth); + return 0; + endfunction + +endpackage : prim_xilinx_pkg diff --git a/hw/ip/prim_xilinx/rtl/prim_xilinx_ram_1p.sv b/hw/ip/prim_xilinx/rtl/prim_xilinx_ram_1p.sv new file mode 100644 index 00000000000000..5f14399faf9c3e --- /dev/null +++ b/hw/ip/prim_xilinx/rtl/prim_xilinx_ram_1p.sv @@ -0,0 +1,77 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Synchronous single-port SRAM model + +`include "prim_assert.sv" + +module prim_xilinx_ram_1p import prim_ram_1p_pkg::*; #( + parameter int Width = 32, // bit + parameter int Depth = 128, + parameter int DataBitsPerMask = 1, // Number of data bits per bit of write mask + parameter MemInitFile = "", // VMEM file to initialize the memory with + + localparam int Aw = $clog2(Depth) // derived parameter +) ( + input logic clk_i, + + input logic req_i, + input logic write_i, + input logic [Aw-1:0] addr_i, + input logic [Width-1:0] wdata_i, + input logic [Width-1:0] wmask_i, + output logic [Width-1:0] rdata_o, // Read data. Data is returned one cycle after req_i is high. + input ram_1p_cfg_t cfg_i +); + + localparam int PrimMaxWidth = prim_xilinx_pkg::get_ram_max_width(Width, Depth); + + if (PrimMaxWidth <= 0) begin : gen_generic + prim_generic_ram_1p #( + .Width(Width), + .Depth(Depth), + .DataBitsPerMask(DataBitsPerMask), + .MemInitFile(MemInitFile) + ) u_ram_1p ( + .* + ); + end else begin : gen + logic wr_en; + assign wr_en = write_i & wmask_i[0]; + + logic unused_cfg_i; + assign unused_cfg_i = cfg_i; + + for (genvar k = 0; k < Width; k = k + PrimMaxWidth) begin : split + localparam int PrimWidth = ((Width - k) > PrimMaxWidth) ? PrimMaxWidth : Width - k; + localparam PrimMemoryInitFile = (MemInitFile != "") ? MemInitFile : "none"; + + xpm_memory_spram #( + .ADDR_WIDTH_A(Aw), + .BYTE_WRITE_WIDTH_A(PrimWidth), // Masks are not supported + .MEMORY_INIT_FILE(PrimMemoryInitFile), + .MEMORY_SIZE(Depth * PrimWidth), + .READ_DATA_WIDTH_A(PrimWidth), + .READ_LATENCY_A(1), + .USE_MEM_INIT_MMI(1), + .WRITE_DATA_WIDTH_A(PrimWidth) + ) u_ram_1p ( + .clka(clk_i), + .addra(addr_i), + .dbiterra(), + .dina(wdata_i[k +: PrimWidth]), + .douta(rdata_o[k +: PrimWidth]), + .ena(req_i), + .injectdbiterra(1'b0), + .injectsbiterra(1'b0), + .regcea(1'b1), + .rsta(1'b0), + .sbiterra(), + .sleep(1'b0), + .wea(wr_en) + ); + end + end + +endmodule diff --git a/hw/ip/prim_xilinx/rtl/prim_xilinx_rom.sv b/hw/ip/prim_xilinx/rtl/prim_xilinx_rom.sv new file mode 100644 index 00000000000000..66b47dc0946afe --- /dev/null +++ b/hw/ip/prim_xilinx/rtl/prim_xilinx_rom.sv @@ -0,0 +1,52 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "prim_assert.sv" + +module prim_xilinx_rom import prim_rom_pkg::*; #( + parameter int Width = 32, + parameter int Depth = 2048, // 8kB default + parameter MemInitFile = "", // VMEM file to initialize the memory with + + localparam int Aw = $clog2(Depth) +) ( + input logic clk_i, + input logic req_i, + input logic [Aw-1:0] addr_i, + output logic [Width-1:0] rdata_o, + input rom_cfg_t cfg_i +); + + localparam PrimMemoryInitFile = (MemInitFile != "") ? MemInitFile : "none"; + localparam PrimMemoryOptimization = (MemInitFile != "") ? "false" : "true"; + + xpm_memory_sprom #( + .ADDR_WIDTH_A(Aw), + .MEMORY_INIT_FILE(PrimMemoryInitFile), + .MEMORY_OPTIMIZATION(PrimMemoryOptimization), + .MEMORY_SIZE(Depth * Width), + .READ_DATA_WIDTH_A(Width), + .READ_LATENCY_A(1), + .USE_MEM_INIT_MMI(1) + ) u_rom ( + .clka(clk_i), + .addra(addr_i), + .dbiterra(), + .douta(rdata_o[k +: PrimWidth]), + .ena(req_i), + .injectdbiterra(1'b0), + .injectsbiterra(1'b0), + .regcea(1'b1), + .rsta(1'b0), + .sbiterra(), + .sleep(1'b0) + ); + + //////////////// + // ASSERTIONS // + //////////////// + + // Control Signals should never be X + `ASSERT(noXOnCsI, !$isunknown(req_i), clk_i, '0) +endmodule diff --git a/hw/ip/prim_xilinx_ultrascale/prim_xilinx_ultrascale_ram_1p.core b/hw/ip/prim_xilinx_ultrascale/prim_xilinx_ultrascale_ram_1p.core new file mode 100644 index 00000000000000..720fe34c26e520 --- /dev/null +++ b/hw/ip/prim_xilinx_ultrascale/prim_xilinx_ultrascale_ram_1p.core @@ -0,0 +1,19 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim_xilinx_ultrascale:ram_1p" +description: "Single port RAM" +filesets: + files_rtl: + depend: + - lowrisc:prim_xilinx:ram_1p + files: + - rtl/prim_xilinx_ultrascale_ram_1p.sv + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_rtl diff --git a/hw/ip/prim_xilinx_ultrascale/rtl/prim_xilinx_ultrascale_ram_1p.sv b/hw/ip/prim_xilinx_ultrascale/rtl/prim_xilinx_ultrascale_ram_1p.sv new file mode 100644 index 00000000000000..7ebdc397f6178d --- /dev/null +++ b/hw/ip/prim_xilinx_ultrascale/rtl/prim_xilinx_ultrascale_ram_1p.sv @@ -0,0 +1,30 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Synchronous single-port SRAM model + +`include "prim_assert.sv" + +module prim_xilinx_ram_1p import prim_ram_1p_pkg::*; #( + parameter int Width = 32, // bit + parameter int Depth = 128, + parameter int DataBitsPerMask = 1, // Number of data bits per bit of write mask + parameter MemInitFile = "", // VMEM file to initialize the memory with + + localparam int Aw = $clog2(Depth) // derived parameter +) ( + input logic clk_i, + + input logic req_i, + input logic write_i, + input logic [Aw-1:0] addr_i, + input logic [Width-1:0] wdata_i, + input logic [Width-1:0] wmask_i, + output logic [Width-1:0] rdata_o, // Read data. Data is returned one cycle after req_i is high. + input ram_1p_cfg_t cfg_i +); + + prim_xilinx_ram_1p #(.*) u_inst (.*); + +endmodule diff --git a/hw/top_earlgrey/chip_earlgrey_cw310.core b/hw/top_earlgrey/chip_earlgrey_cw310.core index 5ed38b7e7d54ce..63a60d53d29409 100644 --- a/hw/top_earlgrey/chip_earlgrey_cw310.core +++ b/hw/top_earlgrey/chip_earlgrey_cw310.core @@ -7,6 +7,7 @@ description: "Earl Grey toplevel for the ChipWhisperer CW310 board" filesets: files_rtl_cw310: depend: + - lowrisc:prim_xilinx:earlgrey_xilinx_prim_pkg - lowrisc:systems:top_earlgrey:0.1 - lowrisc:systems:top_earlgrey_pkg - lowrisc:systems:ast @@ -23,7 +24,6 @@ filesets: - data/clocks.xdc - data/pins_cw310.xdc - data/placement.xdc - - data/synth.xdc file_type: xdc files_tcl: diff --git a/hw/top_earlgrey/chip_earlgrey_cw310_hyperdebug.core b/hw/top_earlgrey/chip_earlgrey_cw310_hyperdebug.core index 74f8ae3c9e96f3..2b9d8a98b19830 100644 --- a/hw/top_earlgrey/chip_earlgrey_cw310_hyperdebug.core +++ b/hw/top_earlgrey/chip_earlgrey_cw310_hyperdebug.core @@ -7,6 +7,7 @@ description: "Earl Grey toplevel for the ChipWhisperer CW310 board's hyperdebug filesets: files_rtl_cw310: depend: + - lowrisc:prim_xilinx:earlgrey_xilinx_prim_pkg - lowrisc:systems:top_earlgrey:0.1 - lowrisc:systems:top_earlgrey_pkg - lowrisc:systems:ast @@ -25,7 +26,6 @@ filesets: # same as lowrisc:systems:chip_earlgrey_cw310. - data/pins_cw310_hyperdebug.xdc - data/placement.xdc - - data/synth.xdc file_type: xdc files_tcl: diff --git a/hw/top_earlgrey/chip_earlgrey_cw340.core b/hw/top_earlgrey/chip_earlgrey_cw340.core index 462f42f771417a..553f2bc8aa3649 100644 --- a/hw/top_earlgrey/chip_earlgrey_cw340.core +++ b/hw/top_earlgrey/chip_earlgrey_cw340.core @@ -7,6 +7,7 @@ description: "Earl Grey toplevel for the ChipWhisperer CW340 board" filesets: files_rtl_cw340: depend: + - lowrisc:prim_xilinx_ultrascale:earlgrey_xilinx_ultrascale_prim_pkg - lowrisc:systems:top_earlgrey:0.1 - lowrisc:systems:top_earlgrey_pkg - lowrisc:systems:ast @@ -22,7 +23,6 @@ filesets: files: - data/clocks_cw341.xdc - data/pins_cw341.xdc - - data/synth.xdc file_type: xdc files_tcl: diff --git a/hw/top_earlgrey/data/synth.xdc b/hw/top_earlgrey/data/synth.xdc deleted file mode 100644 index 2615f456d1e63b..00000000000000 --- a/hw/top_earlgrey/data/synth.xdc +++ /dev/null @@ -1,14 +0,0 @@ -## Copyright lowRISC contributors (OpenTitan project). -## Licensed under the Apache License, Version 2.0, see LICENSE for details. -## SPDX-License-Identifier: Apache-2.0 - -## Synthesis constraints - -# Prevent Vivado from combining these BRAMs, so the memories can be readily -# spliced with updatemem. -set_property KEEP_HIERARCHY TRUE [get_cells "top_earlgrey/u_flash_ctrl/u_eflash/u_flash/gen_generic.u_impl_generic/gen_prim_flash_banks[0].u_prim_flash_bank/gen_info_types[0].u_info_mem"] -set_property KEEP_HIERARCHY TRUE [get_cells "top_earlgrey/u_flash_ctrl/u_eflash/u_flash/gen_generic.u_impl_generic/gen_prim_flash_banks[0].u_prim_flash_bank/gen_info_types[1].u_info_mem"] -set_property KEEP_HIERARCHY TRUE [get_cells "top_earlgrey/u_flash_ctrl/u_eflash/u_flash/gen_generic.u_impl_generic/gen_prim_flash_banks[0].u_prim_flash_bank/gen_info_types[2].u_info_mem"] -set_property KEEP_HIERARCHY TRUE [get_cells "top_earlgrey/u_flash_ctrl/u_eflash/u_flash/gen_generic.u_impl_generic/gen_prim_flash_banks[1].u_prim_flash_bank/gen_info_types[0].u_info_mem"] -set_property KEEP_HIERARCHY TRUE [get_cells "top_earlgrey/u_flash_ctrl/u_eflash/u_flash/gen_generic.u_impl_generic/gen_prim_flash_banks[1].u_prim_flash_bank/gen_info_types[1].u_info_mem"] -set_property KEEP_HIERARCHY TRUE [get_cells "top_earlgrey/u_flash_ctrl/u_eflash/u_flash/gen_generic.u_impl_generic/gen_prim_flash_banks[1].u_prim_flash_bank/gen_info_types[2].u_info_mem"] diff --git a/hw/top_earlgrey/earlgrey_xilinx_prim_pkg.core b/hw/top_earlgrey/earlgrey_xilinx_prim_pkg.core new file mode 100644 index 00000000000000..2284fd3ba0b9a3 --- /dev/null +++ b/hw/top_earlgrey/earlgrey_xilinx_prim_pkg.core @@ -0,0 +1,19 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: "lowrisc:prim_xilinx:earlgrey_xilinx_prim_pkg" +description: "Single port RAM" +virtual: + - lowrisc:prim_xilinx:prim_xilinx_pkg +filesets: + files_rtl: + files: + - rtl/prim_xilinx_pkg.sv + file_type: systemVerilogSource + +targets: + default: &default_target + filesets: + - files_rtl diff --git a/hw/top_earlgrey/rtl/prim_xilinx_pkg.sv b/hw/top_earlgrey/rtl/prim_xilinx_pkg.sv new file mode 100644 index 00000000000000..9595f75e1ebcc4 --- /dev/null +++ b/hw/top_earlgrey/rtl/prim_xilinx_pkg.sv @@ -0,0 +1,14 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package prim_xilinx_pkg; + + function int get_ram_max_width(int width, int depth); + if (width == 76 && depth < 4096) begin + return 64; + end + return 0; + endfunction + +endpackage : prim_xilinx_pkg diff --git a/hw/top_earlgrey/util/vivado_hook_write_bitstream_pre.tcl b/hw/top_earlgrey/util/vivado_hook_write_bitstream_pre.tcl index 26a832965ca8a7..f5f86d9af48f29 100644 --- a/hw/top_earlgrey/util/vivado_hook_write_bitstream_pre.tcl +++ b/hw/top_earlgrey/util/vivado_hook_write_bitstream_pre.tcl @@ -28,6 +28,7 @@ set_property BITSTREAM.CONFIG.USR_ACCESS TIMESTAMP [current_design] # addr_end_multiplier: A coefficient applied to the address space. Influences # the values of the MMI's and # tags. +# schema: Either "Processor" or "MemoryArray" # designtask_count: A number used for logging with `send_msg`. proc generate_mmi {filename mem_infos designtask_count} { send_msg "${designtask_count}-1" INFO "Dumping MMI to ${filename}" @@ -50,6 +51,7 @@ proc generate_mmi {filename mem_infos designtask_count} { # Calculate the overall address space. set space 0 + set width 0 foreach inst [lsort -dictionary $brams] { set slice_begin [get_property ram_slice_begin [get_cells $inst]] set slice_end [get_property ram_slice_end [get_cells $inst]] @@ -69,14 +71,22 @@ proc generate_mmi {filename mem_infos designtask_count} { # Calculate total number of bits. set space [expr {$space + ($addr_end - $addr_begin + 1) * $slice_width}] + set width [expr {$width + $slice_width}] set last_slice_width $slice_width } set space [expr {($space * $addr_end_multiplier / 8) - 1}] # Generate the MMI. - puts $fileout " " - puts $fileout " " - puts $fileout " " + if { $schema eq "Processor" } { + puts $fileout " " + puts $fileout " " + puts $fileout " " + } else { + puts $fileout " " + # Memory type could be retrieved from the RTL_RAM_TYPE property, if desired, + # but we hard-code it here for now. + puts $fileout " " + } foreach inst [lsort -dictionary $brams] { set loc [get_property LOC [get_cells $inst]] @@ -94,15 +104,36 @@ proc generate_mmi {filename mem_infos designtask_count} { set addr_begin [get_property ram_addr_begin [get_cells $inst]] set addr_end [get_property ram_addr_end [get_cells $inst]] set addr_end [expr {($addr_end + 1) * $addr_end_multiplier - 1}] - puts $fileout " " - puts $fileout " " - puts $fileout " " - puts $fileout " " - puts $fileout " " + set bit_layout [get_property "MEM.PORTA.DATA_BIT_LAYOUT" [get_cells $inst]] + set read_width_a [get_property "READ_WIDTH_A" [get_cells $inst]] + set read_width_b [get_property "READ_WIDTH_B" [get_cells $inst]] + set slr_index [get_property "SLR_INDEX" [get_cells $inst]] + if {$schema eq "Processor"} { + puts $fileout " " + puts $fileout " " + puts $fileout " " + puts $fileout " " + puts $fileout " " + } else { + puts $fileout " " + puts $fileout " " + puts $fileout " " + puts $fileout " " + puts $fileout " " + puts $fileout " " + puts $fileout " " + puts $fileout " " + puts $fileout " " + } + } + if {$schema eq "Processor"} { + puts $fileout " " + puts $fileout " " + puts $fileout " " + } else { + puts $fileout " " + puts $fileout " " } - puts $fileout " " - puts $fileout " " - puts $fileout " " } } @@ -189,6 +220,7 @@ dict set memInfo rom brams $rom_brams dict set memInfo rom mem_type_regex $mem_type_regex dict set memInfo rom fake_word_width 40 dict set memInfo rom addr_end_multiplier 1 +dict set memInfo rom schema "Processor" # OTP does not require faking the word width, but it has its own quirk. It seems # each 22-bit OTP word is followed by 15 zero words. The MMI's @@ -200,43 +232,92 @@ dict set memInfo otp brams $otp_brams dict set memInfo otp mem_type_regex $mem_type_regex dict set memInfo otp fake_word_width 0 dict set memInfo otp addr_end_multiplier 16 +dict set memInfo otp schema "Processor" + +# The flash banks have 76-bit wide words. 64 bits are data, and 12 bits are metadata / integrity. +set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[0]*gen_info_types[0].u_info_mem*gen.split[0].*"] " "] +dict set memInfo flash0_info0_data brams $flash_info_brams +dict set memInfo flash0_info0_data mem_type_regex $mem_type_regex +dict set memInfo flash0_info0_data fake_word_width 0 +dict set memInfo flash0_info0_data addr_end_multiplier 1 +dict set memInfo flash0_info0_data schema "MemoryArray" + +set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[0]*gen_info_types[1].u_info_mem*gen.split[0].*"] " "] +dict set memInfo flash0_info1_data brams $flash_info_brams +dict set memInfo flash0_info1_data mem_type_regex $mem_type_regex +dict set memInfo flash0_info1_data fake_word_width 0 +dict set memInfo flash0_info1_data addr_end_multiplier 1 +dict set memInfo flash0_info1_data schema "MemoryArray" + +set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[0]*gen_info_types[2].u_info_mem*gen.split[0].*"] " "] +dict set memInfo flash0_info2_data brams $flash_info_brams +dict set memInfo flash0_info2_data mem_type_regex $mem_type_regex +dict set memInfo flash0_info2_data fake_word_width 0 +dict set memInfo flash0_info2_data addr_end_multiplier 1 +dict set memInfo flash0_info2_data schema "MemoryArray" + +set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[1]*gen_info_types[0].u_info_mem*gen.split[0].*"] " "] +dict set memInfo flash1_info0_data brams $flash_info_brams +dict set memInfo flash1_info0_data mem_type_regex $mem_type_regex +dict set memInfo flash1_info0_data fake_word_width 0 +dict set memInfo flash1_info0_data addr_end_multiplier 1 +dict set memInfo flash1_info0_data schema "MemoryArray" + +set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[1]*gen_info_types[1].u_info_mem*gen.split[0].*"] " "] +dict set memInfo flash1_info1_data brams $flash_info_brams +dict set memInfo flash1_info1_data mem_type_regex $mem_type_regex +dict set memInfo flash1_info1_data fake_word_width 0 +dict set memInfo flash1_info1_data addr_end_multiplier 1 +dict set memInfo flash1_info1_data schema "MemoryArray" + +set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[1]*gen_info_types[2].u_info_mem*gen.split[0].*"] " "] +dict set memInfo flash1_info2_data brams $flash_info_brams +dict set memInfo flash1_info2_data mem_type_regex $mem_type_regex +dict set memInfo flash1_info2_data fake_word_width 0 +dict set memInfo flash1_info2_data addr_end_multiplier 1 +dict set memInfo flash1_info2_data schema "MemoryArray" + +set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[0]*gen_info_types[0].u_info_mem*gen.split[64].*"] " "] +dict set memInfo flash0_info0_intg brams $flash_info_brams +dict set memInfo flash0_info0_intg mem_type_regex $mem_type_regex +dict set memInfo flash0_info0_intg fake_word_width 0 +dict set memInfo flash0_info0_intg addr_end_multiplier 1 +dict set memInfo flash0_info0_intg schema "MemoryArray" + +set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[0]*gen_info_types[1].u_info_mem*gen.split[64].*"] " "] +dict set memInfo flash0_info1_intg brams $flash_info_brams +dict set memInfo flash0_info1_intg mem_type_regex $mem_type_regex +dict set memInfo flash0_info1_intg fake_word_width 0 +dict set memInfo flash0_info1_intg addr_end_multiplier 1 +dict set memInfo flash0_info1_intg schema "MemoryArray" + +set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[0]*gen_info_types[2].u_info_mem*gen.split[64].*"] " "] +dict set memInfo flash0_info2_intg brams $flash_info_brams +dict set memInfo flash0_info2_intg mem_type_regex $mem_type_regex +dict set memInfo flash0_info2_intg fake_word_width 0 +dict set memInfo flash0_info2_intg addr_end_multiplier 1 +dict set memInfo flash0_info2_intg schema "MemoryArray" + +set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[1]*gen_info_types[0].u_info_mem*gen.split[64].*"] " "] +dict set memInfo flash1_info0_intg brams $flash_info_brams +dict set memInfo flash1_info0_intg mem_type_regex $mem_type_regex +dict set memInfo flash1_info0_intg fake_word_width 0 +dict set memInfo flash1_info0_intg addr_end_multiplier 1 +dict set memInfo flash1_info0_intg schema "MemoryArray" + +set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[1]*gen_info_types[1].u_info_mem*gen.split[64].*"] " "] +dict set memInfo flash1_info1_intg brams $flash_info_brams +dict set memInfo flash1_info1_intg mem_type_regex $mem_type_regex +dict set memInfo flash1_info1_intg fake_word_width 0 +dict set memInfo flash1_info1_intg addr_end_multiplier 1 +dict set memInfo flash1_info1_intg schema "MemoryArray" -# The flash banks have 76-bit wide words. 64 bits are data, and 12 bits are metadata. -set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[0]*gen_info_types[0].u_info_mem*"] " "] -dict set memInfo flash0_info0 brams $flash_info_brams -dict set memInfo flash0_info0 mem_type_regex $mem_type_regex -dict set memInfo flash0_info0 fake_word_width 0 -dict set memInfo flash0_info0 addr_end_multiplier 1 - -set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[0]*gen_info_types[1].u_info_mem*"] " "] -dict set memInfo flash0_info1 brams $flash_info_brams -dict set memInfo flash0_info1 mem_type_regex $mem_type_regex -dict set memInfo flash0_info1 fake_word_width 0 -dict set memInfo flash0_info1 addr_end_multiplier 1 - -set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[0]*gen_info_types[2].u_info_mem*"] " "] -dict set memInfo flash0_info2 brams $flash_info_brams -dict set memInfo flash0_info2 mem_type_regex $mem_type_regex -dict set memInfo flash0_info2 fake_word_width 0 -dict set memInfo flash0_info2 addr_end_multiplier 1 - -set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[1]*gen_info_types[0].u_info_mem*"] " "] -dict set memInfo flash1_info0 brams $flash_info_brams -dict set memInfo flash1_info0 mem_type_regex $mem_type_regex -dict set memInfo flash1_info0 fake_word_width 0 -dict set memInfo flash1_info0 addr_end_multiplier 1 - -set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[1]*gen_info_types[1].u_info_mem*"] " "] -dict set memInfo flash1_info1 brams $flash_info_brams -dict set memInfo flash1_info1 mem_type_regex $mem_type_regex -dict set memInfo flash1_info1 fake_word_width 0 -dict set memInfo flash1_info1 addr_end_multiplier 1 - -set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[1]*gen_info_types[2].u_info_mem*"] " "] -dict set memInfo flash1_info2 brams $flash_info_brams -dict set memInfo flash1_info2 mem_type_regex $mem_type_regex -dict set memInfo flash1_info2 fake_word_width 0 -dict set memInfo flash1_info2 addr_end_multiplier 1 +set flash_info_brams [split [get_cells -hierarchical -filter " PRIMITIVE_TYPE =~ ${bram_regex} && NAME =~ *u_flash_ctrl*gen_prim_flash_banks[1]*gen_info_types[2].u_info_mem*gen.split[64].*"] " "] +dict set memInfo flash1_info2_intg brams $flash_info_brams +dict set memInfo flash1_info2_intg mem_type_regex $mem_type_regex +dict set memInfo flash1_info2_intg fake_word_width 0 +dict set memInfo flash1_info2_intg addr_end_multiplier 1 +dict set memInfo flash1_info2_intg schema "MemoryArray" generate_mmi "memories.mmi" $memInfo 1 diff --git a/hw/top_englishbreakfast/chip_englishbreakfast_cw305.core b/hw/top_englishbreakfast/chip_englishbreakfast_cw305.core index edacf154d38571..22b0e1d6d588a6 100644 --- a/hw/top_englishbreakfast/chip_englishbreakfast_cw305.core +++ b/hw/top_englishbreakfast/chip_englishbreakfast_cw305.core @@ -8,6 +8,7 @@ description: "English Breakfast toplevel for the ChipWhisperer CW305 board" filesets: files_rtl_cw305: depend: + - lowrisc:prim_xilinx:prim_xilinx_default_pkg - lowrisc:systems:top_englishbreakfast:0.1 - lowrisc:systems:ast - lowrisc:systems:topgen