Skip to content

Commit

Permalink
flit-gen: Enhance auto-generation (#18)
Browse files Browse the repository at this point in the history
* flit: Align flit generation with floogen

* bender: Fix order of package compilation

* ci: Change QuestaSim version

* test: Small fix for newest QuestaSim version

* flit: Allow generation from outside

* flit: Add some helper functions for XY routing

* flit: Regenerate sources

* flit: Use automatic functions

* flit: And sensible addr offset value

* flit: And regenerate the sources

* Update Changelog
  • Loading branch information
fischeti authored Nov 15, 2023
1 parent 54747cc commit 33498e0
Show file tree
Hide file tree
Showing 14 changed files with 210 additions and 100 deletions.
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Author: Michael Rogenmoser <[email protected]>

variables:
VSIM: 'questa-2022.3 vsim'
VSIM: 'questa-2023.4 vsim'
BENDER: 'bender'
SPYGLASS: 'spyglass-2022.06 sg_shell'

Expand Down
2 changes: 1 addition & 1 deletion Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ export_include_dirs:

sources:
# Level 0
- src/floo_pkg.sv
- src/floo_axi_pkg.sv
- src/floo_narrow_wide_pkg.sv
- src/floo_pkg.sv
# Level 1
- src/floo_cut.sv
- src/floo_fifo.sv
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
### Changed

- Removed `xy_id_i` ports from AXI chimneys in favor of a generic `id_i` port for both `IdTable` and `XYRouting`
- Changed auto-generated package configuration schema. The `header` field is replaced in favor of a `routing` field that better represents the information needed for routing.

### Fixed

Expand Down
12 changes: 7 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,22 @@ endif
# Flit Generation #
###################

FLIT_CFG ?= $(shell find util -name "*.hjson")
FLIT_SRC ?= $(patsubst util/%_cfg.hjson,src/floo_%_pkg.sv,$(FLIT_CFG))
FLIT_OUT_DIR ?= src
FLIT_CFG_DIR ?= util
FLIT_CFG ?= $(shell find $(FLIT_CFG_DIR) -name "*.hjson")
FLIT_SRC ?= $(patsubst $(FLIT_CFG_DIR)/%_cfg.hjson,$(FLIT_OUT_DIR)/floo_%_pkg.sv,$(FLIT_CFG))
FLIT_GEN ?= util/flit_gen.py
FLIT_TPL ?= util/floo_flit_pkg.sv.mako

.PHONY: sources clean-sources

sources: $(FLIT_SRC)
src/floo_%_pkg.sv: util/%_cfg.hjson $(FLIT_GEN) $(FLIT_TPL)
./util/flit_gen.py -c $< > $@
$(FLIT_OUT_DIR)/floo_%_pkg.sv: $(FLIT_CFG_DIR)/%_cfg.hjson $(FLIT_GEN) $(FLIT_TPL)
$(FLIT_GEN) -c $< > $@
$(VERIBLE_FMT) --inplace --try_wrap_long_lines $@

clean-sources:
rm -f src/floo_*_pkg.sv
rm -f $(FLIT_SRC)

######################
# Traffic Generation #
Expand Down
21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,28 +149,27 @@ The AXI channels(s) needs to be configured in `util/*cfg.hjson`. The following e

```
axi_channels: [
{name: 'axi', direction: 'input', params: {dw: 64, aw: 32, iw: 3, uw: 1 }},
{name: 'axi', direction: 'input', params: {dw: 64, aw: 32, iw: 3, uw: 1 }}
]
```
Multiple physical links can be declared and the mapping of the AXI channels to the physical link can be configured in `util/*cfg.json`. The following example shows the configuration for two physical channels, one for requests and one for responses. The mapping of the AXI channels to the physical link is done by specifying the AXI channels in the `map` field.

```
channel_mapping: {
req: {axi: ['aw', 'w', 'ar']},
req: {axi: ['aw', 'w', 'ar']}
rsp: {axi: ['b', 'r']}
},
}
```

FlooNoC does not send any header and tail flits to avoid serilization overhead. Instead additional needed information is sent in parallel and can be specified with the `header` argument and the number of bits required. For instance, the `rob_req` field specifies if a responses needs to be reorderd. The `rob_idx` field specifies the index of the ROB that is used to track the outstanding requests. The `dst_id` & `src_id` fields specifies source and destination to route the packet. The `last` field specifies the last signal of the of a burst transfer used in wormhole routing.
FlooNoC does not send any header and tail flits to avoid serilization overhead. Instead additional needed routing information is sent in parallel and needs to be specified in the `routing` field. Examples for the different routing algorithms can be found in `util/*cfg.hjson`. The following example shows the configuration for a XY routing algorithm with 3-bit X and Y coordinates, 36-bit address offset, and 8-bit RoB index.

```
header: {
rob_req: 1,
rob_idx: 6,
dst_id: 6,
src_id: 6,
last: 1,
atop: 1,
routing: {
route_algo: XYRouting
num_x_bits: 3
num_y_bits: 3
addr_offset_bits: 36
rob_idx_bits: 8
}
```
Finally, the package source files can be generated with:
Expand Down
55 changes: 47 additions & 8 deletions src/floo_axi_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,21 @@

package floo_axi_pkg;

import floo_pkg::*;

////////////////////////
// AXI Parameters //
////////////////////////

typedef enum {
AxiAw = 0,
AxiW = 1,
AxiAr = 2,
AxiB = 3,
AxiR = 4,
NumAxiChannels = 5
} axi_ch_e;

localparam int unsigned AxiInAddrWidth = 32;
localparam int unsigned AxiInDataWidth = 64;
localparam int unsigned AxiInIdWidth = 3;
Expand Down Expand Up @@ -44,22 +55,50 @@ package floo_axi_pkg;
// Header Typedefs //
/////////////////////////

typedef logic [5:0] rob_idx_t;
typedef logic [5:0] dst_id_t;
typedef logic [5:0] src_id_t;
typedef logic [2:0] axi_ch_t;
localparam route_algo_e RouteAlgo = XYRouting;
typedef logic [8:0] rob_idx_t;

localparam int unsigned NumXBits = 3;
localparam int unsigned NumYBits = 3;
localparam int unsigned XAddrOffset = 16;
localparam int unsigned YAddrOffset = 19;

typedef struct packed {
logic [NumXBits-1:0] x;
logic [NumYBits-1:0] y;
} xy_id_t;

function automatic logic [NumXBits-1:0] get_x_coord(logic [31:0] addr);
return addr[XAddrOffset+:NumXBits];
endfunction

function automatic logic [NumYBits-1:0] get_y_coord(logic [31:0] addr);
return addr[YAddrOffset+:NumYBits];
endfunction

function automatic xy_id_t get_xy_id(logic [31:0] addr);
xy_id_t id;
id.x = get_x_coord(addr);
id.y = get_y_coord(addr);
return id;
endfunction

function automatic logic [31:0] get_base_addr(xy_id_t id);
logic [31:0] addr;
addr = id.x << XAddrOffset + id.y << YAddrOffset;
return addr;
endfunction

typedef struct packed {
logic rob_req;
rob_idx_t rob_idx;
dst_id_t dst_id;
src_id_t src_id;
xy_id_t dst_id;
xy_id_t src_id;
logic last;
logic atop;
axi_ch_t axi_ch;
axi_ch_e axi_ch;
} hdr_t;


////////////////////////////
// AXI Flits Typedefs //
////////////////////////////
Expand Down
4 changes: 2 additions & 2 deletions src/floo_narrow_wide_chimney.sv
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ module floo_narrow_wide_chimney
floo_wide_chan_t floo_wide_in;
logic floo_req_in_valid, floo_rsp_in_valid, floo_wide_in_valid;
logic floo_req_out_ready, floo_rsp_out_ready, floo_wide_out_ready;
logic [NumNarrowWideAxiChannels-1:0] axi_valid_in, axi_ready_out;
logic [NumAxiChannels-1:0] axi_valid_in, axi_ready_out;

// Flit packing
floo_narrow_aw_flit_t floo_narrow_aw;
Expand Down Expand Up @@ -182,7 +182,7 @@ module floo_narrow_wide_chimney
} wide_id_out_buf_t;

// Routing
id_t [NumNarrowWideAxiChannels-1:0] dst_id;
id_t [NumAxiChannels-1:0] dst_id;

narrow_id_out_buf_t narrow_aw_out_data_in, narrow_aw_out_data_out;
narrow_id_out_buf_t narrow_ar_out_data_in, narrow_ar_out_data_out;
Expand Down
60 changes: 52 additions & 8 deletions src/floo_narrow_wide_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,26 @@

package floo_narrow_wide_pkg;

import floo_pkg::*;

////////////////////////
// AXI Parameters //
////////////////////////

typedef enum {
NarrowAw = 0,
NarrowW = 1,
NarrowAr = 2,
WideAw = 3,
WideAr = 4,
NarrowB = 5,
NarrowR = 6,
WideB = 7,
WideW = 8,
WideR = 9,
NumAxiChannels = 10
} axi_ch_e;

localparam int unsigned NarrowInAddrWidth = 48;
localparam int unsigned NarrowInDataWidth = 64;
localparam int unsigned NarrowInIdWidth = 4;
Expand Down Expand Up @@ -73,22 +89,50 @@ package floo_narrow_wide_pkg;
// Header Typedefs //
/////////////////////////

typedef logic [7:0] rob_idx_t;
typedef logic [5:0] dst_id_t;
typedef logic [5:0] src_id_t;
typedef logic [3:0] axi_ch_t;
localparam route_algo_e RouteAlgo = XYRouting;
typedef logic [8:0] rob_idx_t;

localparam int unsigned NumXBits = 3;
localparam int unsigned NumYBits = 3;
localparam int unsigned XAddrOffset = 36;
localparam int unsigned YAddrOffset = 39;

typedef struct packed {
logic [NumXBits-1:0] x;
logic [NumYBits-1:0] y;
} xy_id_t;

function automatic logic [NumXBits-1:0] get_x_coord(logic [47:0] addr);
return addr[XAddrOffset+:NumXBits];
endfunction

function automatic logic [NumYBits-1:0] get_y_coord(logic [47:0] addr);
return addr[YAddrOffset+:NumYBits];
endfunction

function automatic xy_id_t get_xy_id(logic [47:0] addr);
xy_id_t id;
id.x = get_x_coord(addr);
id.y = get_y_coord(addr);
return id;
endfunction

function automatic logic [47:0] get_base_addr(xy_id_t id);
logic [47:0] addr;
addr = id.x << XAddrOffset + id.y << YAddrOffset;
return addr;
endfunction

typedef struct packed {
logic rob_req;
rob_idx_t rob_idx;
dst_id_t dst_id;
src_id_t src_id;
xy_id_t dst_id;
xy_id_t src_id;
logic last;
logic atop;
axi_ch_t axi_ch;
axi_ch_e axi_ch;
} hdr_t;


////////////////////////////
// AXI Flits Typedefs //
////////////////////////////
Expand Down
23 changes: 0 additions & 23 deletions src/floo_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,6 @@
/// Currently only contains useful functions and some constants and typedefs
package floo_pkg;

typedef enum logic [3:0] {
NarrowAw,
NarrowW,
NarrowAr,
WideAw,
WideAr,
NarrowB,
NarrowR,
WideB,
WideW,
WideR,
NumNarrowWideAxiChannels
} narrow_wide_axi_ch_e;

typedef enum logic [2:0] {
AxiAw,
AxiW,
AxiAr,
AxiB,
AxiR,
NumAxiChannels
} axi_ch_e;

typedef enum logic[1:0] {
IdIsPort,
IdTable,
Expand Down
2 changes: 1 addition & 1 deletion test/axi_reorder_compare.sv
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ module axi_reorder_compare #(
end

for (genvar i = 0; i < NumSlaves; i++) begin : gen_slv_step_3
always_ff @(posedge clk_i) begin : gen_slv_step_3
always_ff @(posedge clk_i) begin : slv_step_3
if (mon_slv_rsp_i[i].b_valid && mon_slv_req_i[i].b_ready) begin
automatic b_chan_t b;
b = mon_slv_rsp_i[i].b;
Expand Down
19 changes: 9 additions & 10 deletions util/axi_cfg.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,18 @@
{
name: "axi",
protocols: [
{name: 'axi', direction: 'input', params: {dw: 64, aw: 32, iw: 3, uw: 1 }},
{name: 'axi', direction: 'output', params: {dw: 64, aw: 32, iw: 3, uw: 1 }},
{name: 'axi', direction: 'input', params: {dw: 64, aw: 32, iw: 3, uw: 1 }}
{name: 'axi', direction: 'output', params: {dw: 64, aw: 32, iw: 3, uw: 1 }}
]
channel_mapping: {
req: {axi: ['aw', 'w', 'ar']},
req: {axi: ['aw', 'w', 'ar']}
rsp: {axi: ['b', 'r']}
},
header: {
rob_req: 1,
rob_idx: 6,
dst_id: 6,
src_id: 6,
last: 1,
atop: 1,
routing: {
route_algo: XYRouting
num_x_bits: 3
num_y_bits: 3
addr_offset_bits: 16
rob_idx_bits: 8
}
}
1 change: 0 additions & 1 deletion util/flit_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ def main():

kwargs = cfg
kwargs['axi_channels'] = get_axi_chs(**kwargs)
kwargs['header']['axi_ch'] = clog2(len(get_axi_chs(**kwargs)))
kwargs['inv_map'] = get_inverted_mapping(**kwargs)
kwargs['get_axi_channel_sizes'] = get_axi_channel_sizes
kwargs['link_sizes'] = get_link_sizes(**kwargs)
Expand Down
Loading

0 comments on commit 33498e0

Please sign in to comment.