diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e6253858..a359dbc1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,7 +5,7 @@ # Author: Michael Rogenmoser variables: - VSIM: 'questa-2022.3 vsim' + VSIM: 'questa-2023.4 vsim' BENDER: 'bender' SPYGLASS: 'spyglass-2022.06 sg_shell' diff --git a/Bender.yml b/Bender.yml index 8eb96ce4..4fb033f8 100644 --- a/Bender.yml +++ b/Bender.yml @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md index fbe6d144..6fd2a78d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/Makefile b/Makefile index 11347795..a999c434 100644 --- a/Makefile +++ b/Makefile @@ -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 # diff --git a/README.md b/README.md index 01b07a0c..d87e22a1 100644 --- a/README.md +++ b/README.md @@ -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: diff --git a/src/floo_axi_pkg.sv b/src/floo_axi_pkg.sv index 27ceb1cd..d929c4cd 100644 --- a/src/floo_axi_pkg.sv +++ b/src/floo_axi_pkg.sv @@ -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; @@ -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 // //////////////////////////// diff --git a/src/floo_narrow_wide_chimney.sv b/src/floo_narrow_wide_chimney.sv index af9fc85d..bf27da62 100644 --- a/src/floo_narrow_wide_chimney.sv +++ b/src/floo_narrow_wide_chimney.sv @@ -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; @@ -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; diff --git a/src/floo_narrow_wide_pkg.sv b/src/floo_narrow_wide_pkg.sv index 86fa4129..ba0caf6f 100644 --- a/src/floo_narrow_wide_pkg.sv +++ b/src/floo_narrow_wide_pkg.sv @@ -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; @@ -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 // //////////////////////////// diff --git a/src/floo_pkg.sv b/src/floo_pkg.sv index f583d5df..308cac8b 100644 --- a/src/floo_pkg.sv +++ b/src/floo_pkg.sv @@ -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, diff --git a/test/axi_reorder_compare.sv b/test/axi_reorder_compare.sv index 439ab99e..0f0d1b7c 100644 --- a/test/axi_reorder_compare.sv +++ b/test/axi_reorder_compare.sv @@ -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; diff --git a/util/axi_cfg.hjson b/util/axi_cfg.hjson index be2b57a9..0c834b07 100644 --- a/util/axi_cfg.hjson +++ b/util/axi_cfg.hjson @@ -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 } } diff --git a/util/flit_gen.py b/util/flit_gen.py index 643abc53..ef09dbc4 100755 --- a/util/flit_gen.py +++ b/util/flit_gen.py @@ -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) diff --git a/util/floo_flit_pkg.sv.mako b/util/floo_flit_pkg.sv.mako index 1aa44026..124bf4af 100644 --- a/util/floo_flit_pkg.sv.mako +++ b/util/floo_flit_pkg.sv.mako @@ -29,10 +29,25 @@ package floo_${name}_pkg; + import floo_pkg::*; + //////////////////////// // AXI Parameters // //////////////////////// +<% i = 0 %> \ + typedef enum { +% for phys_ch, mapping in channel_mapping.items(): + % for ch_type, axi_chs in mapping.items(): + % for axi_ch in axi_chs: + ${camelcase(f"{ch_type}_{axi_ch}")} = ${i}, + <% i += 1 %> \ + % endfor + % endfor +% endfor + NumAxiChannels = ${i} + } axi_ch_e; + % for prot in protocols: localparam int unsigned ${camelcase(prot_full_name(**prot, prefix=''))}AddrWidth = ${prot['params']['aw']}; localparam int unsigned ${camelcase(prot_full_name(**prot, prefix=''))}DataWidth = ${prot['params']['dw']}; @@ -56,22 +71,58 @@ package floo_${name}_pkg; // Header Typedefs // ///////////////////////// -% for m, l in header.items(): - % if l > 1: - typedef logic [${l-1}:0] ${m}_t; - % endif -% endfor + localparam route_algo_e RouteAlgo = ${routing['route_algo']}; + typedef logic [${routing['rob_idx_bits']}:0] rob_idx_t; + +% if routing['route_algo'] == 'XYRouting': + localparam int unsigned NumXBits = ${routing['num_x_bits']}; + localparam int unsigned NumYBits = ${routing['num_y_bits']}; + localparam int unsigned XAddrOffset = ${routing['addr_offset_bits']}; + localparam int unsigned YAddrOffset = ${routing['addr_offset_bits'] + routing['num_x_bits']}; typedef struct packed { - % for m, l in header.items(): - % if l == 1: - logic ${m}; - % else: - ${m}_t ${m}; - % endif - % endfor - } hdr_t; + logic [NumXBits-1:0] x; + logic [NumYBits-1:0] y; + } xy_id_t; + + function automatic logic [NumXBits-1:0] get_x_coord(logic [${protocols[0]['params']['aw']-1}:0] addr); + return addr[XAddrOffset +: NumXBits]; + endfunction + + function automatic logic [NumYBits-1:0] get_y_coord(logic [${protocols[0]['params']['aw']-1}:0] addr); + return addr[YAddrOffset +: NumYBits]; + endfunction + + function automatic xy_id_t get_xy_id(logic [${protocols[0]['params']['aw']-1}:0] addr); + xy_id_t id; + id.x = get_x_coord(addr); + id.y = get_y_coord(addr); + return id; + endfunction + + function automatic logic [${protocols[0]['params']['aw']-1}:0] get_base_addr(xy_id_t id); + logic [${protocols[0]['params']['aw']-1}:0] addr; + addr = id.x << XAddrOffset + id.y << YAddrOffset; + return addr; + endfunction +% elif routing['route_algo'] == 'IdTable': + typedef logic [${routing['num_id_bits']-1}:0] id_t; +% endif + typedef struct packed { + logic rob_req; + rob_idx_t rob_idx; +% if routing['route_algo'] == 'XYRouting': + xy_id_t dst_id; + xy_id_t src_id; +% elif routing['route_algo'] == 'IdTable': + id_t dst_id; + id_t src_id; +% endif + logic last; + logic atop; + axi_ch_e axi_ch; + } hdr_t; //////////////////////////// // AXI Flits Typedefs // diff --git a/util/narrow_wide_cfg.hjson b/util/narrow_wide_cfg.hjson index 5fb24ed6..fc537fb1 100644 --- a/util/narrow_wide_cfg.hjson +++ b/util/narrow_wide_cfg.hjson @@ -7,30 +7,29 @@ { name: "narrow_wide", protocols: [ - {name: 'narrow', direction: 'input', params: {dw: 64, aw: 48, iw: 4, uw: 5 }}, - {name: 'narrow', direction: 'output', params: {dw: 64, aw: 48, iw: 2, uw: 5 }}, - {name: 'wide', direction: 'input', params: {dw: 512, aw: 48, iw: 3, uw: 1 }}, - {name: 'wide', direction: 'output', params: {dw: 512, aw: 48, iw: 1, uw: 1 }}, + {name: 'narrow', direction: 'input', params: {dw: 64, aw: 48, iw: 4, uw: 5 }} + {name: 'narrow', direction: 'output', params: {dw: 64, aw: 48, iw: 2, uw: 5 }} + {name: 'wide', direction: 'input', params: {dw: 512, aw: 48, iw: 3, uw: 1 }} + {name: 'wide', direction: 'output', params: {dw: 512, aw: 48, iw: 1, uw: 1 }} ] channel_mapping: { req: { - narrow: ['aw', 'w', 'ar'], + narrow: ['aw', 'w', 'ar'] wide: ['aw', 'ar'] - }, + } rsp: { - narrow: ['b', 'r'], + narrow: ['b', 'r'] wide: ['b'] - }, + } wide: { wide: ['w', 'r'] } - }, - header: { - rob_req: 1, - rob_idx: 8, - 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 } }