Skip to content

Commit

Permalink
Draft: create parametric top.
Browse files Browse the repository at this point in the history
  • Loading branch information
Yvan Tortorella committed Dec 30, 2023
1 parent 8ce68b7 commit 17e30d8
Show file tree
Hide file tree
Showing 6 changed files with 790 additions and 350 deletions.
1 change: 1 addition & 0 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ sources:
# package. Files in level 1 only depend on files in level 0, files in level 2 on files in
# levels 1 and 0, etc. Files within a level are ordered alphabetically.
# Level 0
- hw/carfield_cfg_pkg.sv
- hw/carfield_pkg.sv
- hw/regs/carfield_reg_pkg.sv
- hw/regs/carfield_reg_top.sv
Expand Down
363 changes: 180 additions & 183 deletions hw/carfield.sv

Large diffs are not rendered by default.

229 changes: 229 additions & 0 deletions hw/carfield_cfg_pkg.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
// Copyright 2022 ETH Zurich and University of Bologna.
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51
//
// Yvan Tortorella <[email protected]>

/// Configuration package
package carfield_cfg_pkg;

import cheshire_pkg::*;

// Structure where each field defines if an island
// is present or not. 1: present; 0: not present.
typedef struct packed {
bit l2;
bit l2_dualport;
bit safed;
bit ethernet;
bit periph;
bit spatz;
bit pulp;
bit secured;
} enable_islands_t;

// Structure used to define the address range of each island.
// N.B. island_cfg_t and enable_islands_t structures could be
// packed into a single one.
typedef struct packed {
doub_bt l2_port0_base;
doub_bt l2_port1_base;
doub_bt l2_size;
doub_bt safed_base;
doub_bt safed_size;
doub_bt ethernet_base;
doub_bt ethernet_size;
doub_bt periph_base;
doub_bt periph_size;
doub_bt spatz_base;
doub_bt spatz_size;
doub_bt pulp_base;
doub_bt pulp_size;
doub_bt otmbox_base;
doub_bt otmbox_size;
} island_cfg_t;

// Types are obtained from Cheshire package
// Parameter MaxExtAxiSlvWidth is obtained from Cheshire
// Structure used to create the AXI map to be passed to
// the Cheshire configuration parameter to create the
// AXI crossbar.
typedef struct packed {
byte_bt [2**MaxExtAxiSlvWidth-1:0] AxiIdx;
doub_bt [2**MaxExtAxiSlvWidth-1:0] AxiStart;
doub_bt [2**MaxExtAxiSlvWidth-1:0] AxiEnd;
} axi_struct_t;

typedef struct packed {
byte_bt l2_port0;
byte_bt l2_port1;
byte_bt safed;
byte_bt ethernet;
byte_bt periph;
byte_bt spatz;
byte_bt pulp;
byte_bt mbox;
} carfield_slave_idx_t;

typedef struct packed {
byte_bt safed;
byte_bt spatz;
byte_bt pulp;
byte_bt secured;
} carfield_master_idx_t;

// TODO: specify this is for AXI
// Generate the number of AXI slave devices to be connected to the
// crossbar starting from the islands enable structure.
function automatic int unsigned gen_num_slave(enable_islands_t en);
int unsigned ret = 0; // Number of slaves starts from 0
if (en.l2) begin
ret++; // If we enable L2, we increase by 1
if (en.l2_dualport)
ret++; // If the L2 is dualport, increase again
end
if (en.safed ) begin ret++; end
if (en.periph ) begin ret++; end
if (en.ethernet) begin ret++; end
if (en.spatz ) begin ret++; end
if (en.pulp ) begin ret++; end
if (en.secured ) begin ret++; end
return ret;
endfunction

// TODO: specify this is for AXI
// Generate the IDs for each AXI slave device
function automatic carfield_slave_idx_t carfield_gen_slave_idx(enable_islands_t en);
carfield_slave_idx_t ret = 0; // Initialize struct first
unsigned int i = 0;
if (en.l2) begin ret.l2_port0 = i; i++;
if (en.l2_dualport) begin ret.l2_port1 = i; i++; end
end
if (en.safed ) begin ret.safed = i; i++; end
if (en.ethernet) begin ret.ethernet = i; i++; end
if (en.periph ) begin ret.periph = i; i++; end
if (en.spatz ) begin ret.spatz = i; i++; end
if (en.pulp ) begin ret.pulp = i; i++; end
if (en.secured ) begin ret.mbox = i; i++; end
return ret;
endfunction

// TODO: specify this is for AXI
// Generate the number of AXI master devices that connect to the
// crossbar starting from the islands enable structure.
function automatic int unsigned gen_num_master(enable_islands_t en);
int unsigned ret = 0; // Number of masters starts from 0
if (en.safed ) begin ret++; end
if (en.spatz ) begin ret++; end
if (en.pulp ) begin ret++; end
if (en.secured) begin ret++; end
return ret;
endfunction

// TODO: specify this is for AXI
// Generate the IDs for each AXI master device
function automatic carfield_master_idx_t carfield_gen_master_idx(enable_islands_t en);
carfield_master_idx_t ret = 0; // Initialize struct first
unsigned int i = 0;
if (en.safed ) begin ret.safed = i; i++; end
if (en.spatz ) begin ret.spatz = i; i++; end
if (en.pulp ) begin ret.pulp = i; i++; end
if (en.secured ) begin ret.secured = i; i++; end
return ret;
endfunction

// Starting from the islands map and the islands enable structures,
// this function will generate structure to be passed for the
// generation or not of AXI crossbar ports for each slave.
function automatic axi_struct_t carfield_gen_axi_map(int unsigned NumSlave, enable_islands_t en_islands, island_cfg_t island_cfg);
axi_struct_t ret = '0; // Initialize the map first
int unsigned i = 0;
if (en_islands.l2) begin
ret.AxiIdx[i] = i;
ret.AxiStart[i] = island_cfg.l2_port0_base;
ret.AxiEnd[i] = island_cfg.l2_port0_base + island_cfg.l2_size;
if (i < NumSlave - 1) i++;
if (en_islands.l2_dualport) begin
ret.AxiIdx[i] = i;
ret.AxiStart[i] = island_cfg.l2_port1_base;
ret.AxiEnd[i] = island_cfg.l2_port1_base + island_cfg.l2_size;
if (i < NumSlave - 1) i++;
end
end
if (en_islands.safed) begin
ret.AxiIdx[i] = i;
ret.AxiStart[i] = island_cfg.safed_base;
ret.AxiEnd[i] = island_cfg.safed_base + island_cfg.safed_size;
if (i < NumSlave - 1) i++;
end
if (en_islands.ethernet) begin
ret.AxiIdx[i] = i;
ret.AxiStart[i] = island_cfg.ethernet_base;
ret.AxiEnd[i] = island_cfg.ethernet_base + island_cfg.ethernet_size;
if (i < NumSlave - 1) i++;
end
if (en_islands.periph) begin
ret.AxiIdx[i] = i;
ret.AxiStart[i] = island_cfg.periph_base;
ret.AxiEnd[i] = island_cfg.periph_base + island_cfg.periph_size;
if (i < NumSlave - 1) i++;
end
if (en_islands.spatz) begin
ret.AxiIdx[i] = i;
ret.AxiStart[i] = island_cfg.spatz_base;
ret.AxiEnd[i] = island_cfg.spatz_base + island_cfg.spatz_size;
if (i < NumSlave - 1) i++;
end
if (en_islands.pulp) begin
ret.AxiIdx[i] = i;
ret.AxiStart[i] = island_cfg.pulp_base;
ret.AxiEnd[i] = island_cfg.pulp_base + island_cfg.pulp_size;
if (i < NumSlave - 1) i++;
end
if (en_islands.secured) begin
ret.AxiIdx[i] = i;
ret.AxiStart[i] = island_cfg.otmbox_base;
ret.AxiEnd[i] = island_cfg.otmbox_base + island_cfg.otmbox_size;
if (i < NumSlave - 1) i++;
end
return ret;
endfunction

localparam enable_islands_t CarfieldEnIslands = '{
l2: 1,
l2_dualport: 1,
safed: 1,
ethernet: 0,
periph: 1,
spatz: 1,
pulp: 1,
secured: 1
};

localparam island_cfg_t CarfieldIslandCfg = '{
l2_port0_base: 'h78000000,
l2_port1_base: 'h78200000,
l2_size: 'h00200000,
safed_base: 'h60000000,
safed_size: 'h00800000,
ethernet_base: 'h20000000,
ethernet_size: 'h00001000,
periph_base: 'h20001000,
periph_size: 'h00009000,
spatz_base: 'h51000000,
spatz_size: 'h00800000,
pulp_base: 'h50000000,
pulp_size: 'h00800000,
otmbox_base: 'h40000000,
otmbox_size: 'h00001000
};

// TODO: specify this is for AXI
localparam int unsigned CarfieldNumSlaves = gen_num_slave(CarfieldEnIslands);
localparam carfield_slave_idx_t CarfieldSlvIdx = carfield_gen_slave_idx(CarfieldEnIslands);
localparam int unsigned CarfieldNumMasters = gen_num_master(CarfieldEnIslands);
localparam carfield_master_idx_t CarfieldMstIdx = carfield_gen_master_idx(CarfieldEnIslands);

localparam axi_struct_t CarfieldAxiMap = carfield_gen_axi_map(CarfieldNumSlaves, CarfieldEnIslands, CarfieldIslandCfg);

endpackage
Loading

0 comments on commit 17e30d8

Please sign in to comment.