Git Product home page Git Product logo

axi's Introduction

AXI SystemVerilog Modules for High-Performance On-Chip Communication

CI status GitHub tag (latest SemVer) SHL-0.51 license

This repository provides modules to build on-chip communication networks adhering to the AXI4 or AXI4-Lite standards. For high-performance communication, we implement AXI4+ATOPs from AXI5. For lightweight communication, we implement AXI4-Lite. We aim to provide a complete end-to-end communication platform, including endpoints such as DMA engines and on-chip memory controllers.

Our design goals are:

  • Topology Independence: We provide elementary building blocks such as protocol multiplexers and demultiplexers that allow users to implement any network topology. We also provide commonly used interconnecting components such as a crossbar.
  • Modularity: We favor design by composition over design by configuration where possible. We strive to apply the Unix philosophy to hardware: make each module do one thing well. This means you will more often instantiate our modules back-to-back than change a parameter value to build more specialized networks.
  • Fit for Heterogeneous Networks: Our modules are parametrizable in terms of data width and transaction concurrency. This allows to create optimized networks for a wide range of performance (e.g., bandwidth, concurrency, timing), power, and area requirements. We provide modules such as data width converters and ID width converters that allow to join subnetworks with different properties, creating heterogeneous on-chip networks.
  • Full AXI Standard Compliance.
  • Compatibility with a wide range of (recent versions of) EDA tools and implementation in standardized synthesizable SystemVerilog.

The design and microarchitecture of the modules in this repository is described in this paper (preprint). If you use our work in your research, please cite it.

List of Modules

In addition to the documents linked in the following table, we are setting up documentation auto-generated from inline docstrings. (Replace master in that URL with a tag to get the documentation for a specific version.)

Name Description Doc
axi_atop_filter Filters atomic operations (ATOPs), i.e., write transactions that have a non-zero aw_atop value.
axi_burst_splitter Split AXI4 burst transfers into single-beat transactions.
axi_cdc AXI clock domain crossing based on a Gray FIFO implementation.
axi_cut Breaks all combinatorial paths between its input and output.
axi_delayer Synthesizable module which can (randomly) delays AXI channels.
axi_demux_simple Demux without spill registers. Doc
axi_demux Demultiplexes an AXI bus from one slave port to multiple master ports. Doc
axi_dw_converter A data width converter between AXI interfaces of any data width.
axi_dw_downsizer A data width converter between a wide AXI master and a narrower AXI slave.
axi_dw_upsizer A data width converter between a narrow AXI master and a wider AXI slave.
axi_err_slv Always responds with an AXI decode/slave error for transactions which are sent to it.
axi_fifo A Fifo for each AXI4 channel to buffer requests.
axi_from_mem This module acts like an SRAM and makes AXI4 requests downstream.
axi_id_prepend This module prepends/strips the MSB from the AXI IDs.
axi_id_remap Remap AXI IDs from wide IDs at the slave port to narrower IDs at the master port. Doc
axi_id_serialize Reduce AXI IDs by serializing transactions when necessary. Doc
axi_interleaved_xbar Interleaved version of the crossbar. This module is experimental; use at your own risk.
axi_intf This file defines the interfaces we support.
axi_isolate A module that can isolate downstream slaves from receiving new AXI4 transactions.
axi_iw_converter Convert between any two AXI ID widths. Doc
axi_join A connector that joins two AXI interfaces.
axi_lfsr AXI4-attached LFSR; read returns pseudo-random data, writes are compressed into a checksum.
axi_lite_demux Demultiplexes an AXI4-Lite bus from one slave port to multiple master ports. Doc
axi_lite_dw_converter A data width converter between two AXI-Lite busses [Doc][doc.axi_lite_dw_converter]
axi_lite_from_mem This module acts like an SRAM and makes AXI4-Lite requests downstream.
axi_lite_join A connector that joins two AXI-Lite interfaces.
axi_lite_lfsr AXI4-Lite-attached LFSR; read returns pseudo-random data, writes are compressed into a checksum.
axi_lite_mailbox A AXI4-Lite Mailbox with two slave ports and usage triggered irq. Doc
axi_lite_mux Multiplexes AXI4-Lite slave ports down to one master port. Doc
axi_lite_regs AXI4-Lite registers with optional read-only and protection features. Doc
axi_lite_to_apb AXI4-Lite to APB4 protocol converter.
axi_lite_to_axi AXI4-Lite to AXI4 protocol converter.
axi_lite_xbar Fully-connected AXI4-Lite crossbar with an arbitrary number of slave and master ports. Doc
axi_modify_address A connector that allows addresses of AXI requests to be changed.
axi_multicut AXI register which can be used to relax timing pressure on long AXI buses.
axi_mux Multiplexes the AXI4 slave ports down to one master port. Doc
axi_pkg Contains AXI definitions, common structs, and useful helper functions.
axi_rw_join Joins a read and a write slave into one single read / write master.
axi_rw_split Splits a single read / write slave into one read and one write master.
axi_serializer Serializes transactions with different IDs to the same ID.
axi_slave_compare Compares two slave devices.
axi_throttle Limits the maximum number of outstanding transfers sent to the downstream logic.
axi_test A set of testbench utilities for AXI interfaces.
axi_to_axi_lite AXI4 to AXI4-Lite protocol converter.
axi_to_mem AXI4 to memory protocol (req, gnt, rvalid) converter. Additional banked, interleaved, split variant.
axi_xbar Fully-connected AXI4+ATOP crossbar with an arbitrary number of slave and master ports. Doc
axi_xp AXI Crosspoint (XP) with homomorphous slave and master ports.
axi_zero_mem AXI-attached /dev/zero. All reads will be zero, writes are absorbed.

Synthesizable Verification Modules

The following modules are meant to be used for verification purposes only but are synthesizable to be used in FPGA environments.

Name Description
axi_bus_compare Compares two buses of the same type (and in the same clock domain), returns events on mismatch.
axi_slave_compare Compares two slave devices of the same type (and in the same clock domain), returns events on mismatch.

Simulation-Only Modules

In addition to the modules above, which are available in synthesis and simulation, the following modules are available only in simulation. Those modules are widely used in our testbenches, but they are also suitable to build testbenches for AXI modules and systems outside this repository.

Name Description
axi_chan_compare Non-synthesizable module comparing two AXI channels of the same type
axi_chan_logger Logs the transactions of an AXI4(+ATOPs) port to files.
axi_driver Low-level driver for AXI4(+ATOPs) that can send and receive individual beats on any channel.
axi_dumper Dumps log to file to be interpreted by axi_dumper_interpret script for debugging purposes.
axi_file_master AXI4 master for file-based testbenches
axi_lite_driver Low-level driver for AXI4-Lite that can send and receive individual beats on any channel.
axi_lite_rand_master AXI4-Lite master component that issues random transactions within user-defined constraints.
axi_lite_rand_slave AXI4-Lite slave component that responds to transactions with constrainable random delays and data.
axi_rand_master AXI4(+ATOPs) master component that issues random transactions within user-defined constraints.
axi_rand_slave AXI4(+ATOPs) slave component that responds to transactions with constrainable random delays and data.
axi_scoreboard Scoreboard that models a memory that only gets changed by the monitored AXI4(+ATOPs) port.
axi_sim_mem Infinite memory with AXI4 slave port.

Atomic Operations

AXI4+ATOPs means the full AXI4 specification plus atomic operations (ATOPs) as defined in Section E1.1 of the AMBA 5 specification. This has the following implications for modules that do not implement ATOPs and systems that include such modules:

  • Masters that do not issue ATOPs must set aw_atop to '0.
  • Slaves that do not support ATOPs must specify this in their interface documentation and can ignore the aw_atop signal.
  • System designers are responsible for ensuring that
    1. slaves that do not support ATOPs are behind an axi_atop_filter if any master could issue an ATOP to such slaves and
    2. the aw_atop signal is well-defined at the input of any (non-AXI4-Lite) module in this repository.

Masters and slaves that do support ATOPs must adhere to Section E1.1 of the AMBA 5 specification. In particular:

  • ATOPs that have the aw_atop[axi_pkg::ATOP_R_RESP] bit set generate a write response (B channel) beat and at least one read response (R channel) beat. All modules for which the aw_atop[axi_pkg::ATOP_R_RESP] bit could be set at their master port must be able to handle both B and R beats (in any order and without requiring a simultaneous handshake) for each such ATOP request. All modules for which the aw_atop[axi_pkg::ATOP_R_RESP] bit could be set at their slave port must respond with the appropriate number of B and R beats for each such ATOP request.
  • ATOPs must not use the same AXI ID as any other transaction that is outstanding at the same time.

Which EDA Tools Are Supported?

Our code is written in standard SystemVerilog (IEEE 1800-2012, to be precise), so the more important question is: Which subset of SystemVerilog does your EDA tool support?

We aim to be compatible with a wide range of EDA tools. For this reason, we strive to use as simple language constructs as possible, especially for our synthesizable modules. We encourage contributions that further simplify our code to make it compatible with even more EDA tools. We also welcome contributions that work around problems that specific EDA tools may have with our code, as long as:

  • the EDA tool is reasonably widely used,
  • recent versions of the EDA tool are affected,
  • the workaround does not break functionality in other tools, and
  • the workaround does not significantly complicate code or add maintenance overhead.

In addition, we suggest to report issues with the SystemVerilog language support directly to the EDA vendor. Our code is fully open and can / should be shared with the EDA vendor as a testcase for any language problem encountered.

All code in each release and on the default branch is tested on a recent version of at least one industry-standard RTL simulator and synthesizer. You can examine the CI settings to find out which version of which tool we are running.

axi's People

Contributors

andreaskurth avatar andreaskuster avatar anga93 avatar bluewww avatar cfuguet avatar colluca avatar cyrilkoe avatar dawidzim avatar fabianschuiki avatar felixonmars avatar fischeti avatar huettern avatar jmdeharor avatar jsailer avatar luca-valente avatar lucazulberti avatar micprog avatar niwis avatar olofk avatar paulsc96 avatar samuelriedel avatar skokvermon avatar stevobailey avatar stmach avatar suehtamacv avatar thommythomaso avatar uge avatar vyae avatar wroenninger avatar zarubaf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

axi's Issues

Separating master and slave of AXI-lite

Hi,
I am working on AXI-complaint DMA. I have to use the master and slave of AXI-lite separately. I am a bit confused which modules will constitute the master and slave. If i am thinking in the wrong direction kindly correct me. Thanks a lot.
Best regards.

`axi_demux`: Slave port stalling if the master issues writes depending on reads.

There can be instances where the slave port on axi_demux deadlocks if the connected master module generates AW transactions depending on AR transactions (as can happen when #110 is connected to a axi_xabr).

In addition the master has to be capable to launch more transactions than the xbar can forward (depending on MaxMstTrans).
Then the instantiated id counters of the AR in axi_demux can stall the AW path due to handling of the ATOP inject. This then causes the AWs to stall and not letting W through. This leads to stalling of the R channel, which causes the AR in the id counters not being retired, leading to a deadlock.

This can at the moment be prevented by setting MaxMstTrans to a value such that the id_counters never start stalling.

VCS compilation issue for AXI lite modules

Please see the following error message shown by vcs

Error-[SV-UIP] Unconnected interface port
axi_lite_demux.sv, 421
"slv"
The port 'slv' of top-level module 'axi_lite_demux_intf' whose type is
interface 'AXI_LITE' is left unconnected. It is illegal to leave the
interface ports unconnected.
Please make sure that all the interface ports are connected.

Definition of AxiIdWidthSlaves in tb_axi_xbar

Additional bits in AxiIdWidthSlaves are used to figure out which master is sending request to that slave, so ideally this should be $clog2(NoMasters).

I believe this didn't cause problems in default tb since NoSlaves > NoMasters, and RTL ignores extra MSB.

localparam int unsigned AxiIdWidthSlaves = AxiIdWidthMasters + $clog2(NoSlaves);

Consider checking rtl with `vlog -lint -pedanticerrors`

Some code does not compile with -pedanticerrors (strict langauge checks) for example

git clone [email protected]:pulp-platform/common_verification.git
vlog -lint -pedanticerrors common_verification/src/rand_id_queue.sv
vlog -lint -pedanticerrors src/axi_pkg.sv
vlog -lint -pedanticerrors src/axi_test.sv

results in

** Error (suppressible): src/axi_test.sv(72): (vlog-13262) A virtual interface element is not allowed in a sensitivity list.
** Error (suppressible): src/axi_test.sv(356): (vlog-13262) A virtual interface element is not allowed in a sensitivity list.
** Error (suppressible): src/axi_test.sv(965): (vlog-13262) A virtual interface element is not allowed in a sensitivity list.
** Error (suppressible): src/axi_test.sv(1207): (vlog-13262) A virtual interface element is not allowed in a sensitivity list.
** Error (suppressible): src/axi_test.sv(1357): (vlog-13262) A virtual interface element is not allowed in a sensitivity list.
** Error (suppressible): src/axi_test.sv(1514): (vlog-13262) A virtual interface element is not allowed in a sensitivity list.
** Error (suppressible): src/axi_test.sv(1683): (vlog-13262) A virtual interface element is not allowed in a sensitivity list.
verror vlog-13262

[...] LRM Section 25.9: 'they [virtual interface elements] cannot be used
in continuous assignments or sensitivity lists'.

I believe it is useful to limit ourselves to the sv standard, since it will improve compatibility between different vendor tools.

Question regarding using pulp_axi

I am planning to use pulp_axi module for an interface between CSRs of my RISC-V processor and an accelerator. The idea here is to control the accelerator with the configuration registers that are set by SW in the CSR module.

  1. I was wondering which axi interface do you recommend?
  2. Also, what are the minimum pulp blocks I need to use?
  3. Finally I am planning to implement my system on a Xilinx FPGA and since I might move toward ASIC implementation, do you recommend to use Xilinx IPs for FPGA and your IPs for ASIC or can I use your IPS for both scenario?

Naming convention for ports

All our interfaces have two modports: Slave and Master. This is aligned with the AXI terminology (and the only reason we are calling them like that). The ports themselves, however, are called slv/mst in 7/6 modules, in/out in 4/5 modules, and src/dst in 1/1 module. I think this is confusing and we should stick to a single convention. In alignment with the AXI standard and the majority of our modules, I propose slv and mst.

The situation is much better for request and response structs. We consistently use slv/mst with the exception of one module, axi_cdc.

Opinions?

Formal Verification of AXI-Lite Crossbar

I was running a formal verification check on the AXI-lite crossbar, and saw that it is no longer in the repository. Can any one tell me the status of the core? Should I expect it to be working? or did it ever work?

Thanks!

axi_lite_xbar component arbitration

I am leveraging the axi_lite_xbar component to interface a hardware architecture processor to a variety of peripherals. As I am not terribly concerned with performance, I set it up to have two masters: instruction bus and data bus. Unfortunately, while the axi_lite_xbar has arbiters in it, reads and writes are separated. When I have the instruction bus (master 0) doing lots of reads, and the data bus (master 1) try to do a write, it seems to be permanently stalled. Is it possible to arbitrate reads and writes across all masters?

  • Brendon

Verilator compile issues

I am working on simulating the AXI4 code in Verilator and are running into a problem with the parameter types of the modules. The issue is the parameter type resp_t = logic definition in al modules. However renaming the definitions to parameter type rsp_t = logic seems to not trigger the issue. I think the issue could be that in axi_pkg the parameter resp_t is already defined and part of the response struct which is the parameter which has this problem.
Should I do a fix for all modules, this will however break all other projects which are using the new AXI4 infrastructure currently.

Related to Verilator: In #43 there is in file src/axi_dw_upsizer.sv line 321 a struct definition for r_req_d and r_req_q inside a generate. Verilator complains about multiple type definitions.
I was able to fix this by declaring a separate typedef outside the generate and defining the signals separate in the generate:

typedef struct packed {
      ar_chan_t ar         ;
      logic ar_valid       ;
      logic ar_throw_error ;
      slv_r_chan_t r       ;
      logic r_valid        ;
      burst_len_t burst_len;
      size_t orig_ar_size  ;
} r_req_t;

// code

for (genvar ...
  r_req_t r_req_d, r_req_q;
end

Test driver compliance with AXI spec

The current test-driver in axi_test.sv waits for axi.aw_ready to be high in the send_aw task before trying the send_w task. I think this test-driver is not compliant with the AXI spec. AXI4 write response dependency sub-section in section A3.3 of the spec says that

the master must not wait for the slave to assert AWREADY or WREADY before asserting AWVALID or WVALID

the slave can wait for AWVALID or WVALID, or both, before asserting AWREADY

Thus the test-bench can potentially fail an otherwise correct crossbar implementation. I might try to edit the test-driver to fix this and was wondering if you have any thoughts on a simple fix.

axi_xbar: Change default master port setting from input to parameter

Currently, the default master port feature of axi_xbar is set by the input signals en_default_mst_port_i and default_mst_port_i instead of by parameters.

The advantage of using input signals is that the default master port can be activated/deactivated and changed at run time. However, this may only happen when there is no unserved Ax beat. There are assertions that check that, but this restriction is not enforced in the synthesized logic. (Although it would be possible to enforce it in the synthesized logic at the expense of a few extra registers). Additionally, it is questionable whether changing the default port at run time has a real use case and therefore is a relevant feature.

The advantage of using parameters would be that the activation of a default master port allows to omit the instantiation of the internal error slave, which also reduces the number of master ports on each of the internal demultiplexers by one. Additionally, for a crossbar with a single master port, this would allow to entirely omit the demultiplexer at each slave port. This is especially relevant in networks with high ID widths, where demultiplexers are very expensive.

Data width converter violates AXI protocol on waiting for `aw_ready`

In axi_dw_downsizer.sv, the write channel does not proceed until the write address channel has finished its handshake (see here):

   // Can start a new request as soon as w_state_d is W_IDLE
    if (w_state_d == W_IDLE) begin
      // Reset channels
      w_req_d.aw = '0;

      if (slv_req_i.aw_valid && slv_req_i.aw.atop[5]) begin // ATOP with an R response
        inject_aw_into_ar_req = 1'b1                 ;
        slv_resp_o.aw_ready   = inject_aw_into_ar_gnt;
      end else begin // Regular AW
        slv_resp_o.aw_ready = 1'b1;
      end

      // New write request
      if (slv_req_i.aw_valid && slv_resp_o.aw_ready) begin
        // Default state
        w_state_d = W_PASSTHROUGH;

This is a violation of the AXI 4 protocol where a slave can wait for both aw_valid and w_valid to be asserted.

Build and deploy documentation is failing.

When the CI runs, the build and deploy documentation fails with following output in Determine documentation target folder:

Run if echo $GITHUB_REF | grep -qE '^refs/(heads|tags)'; then
Error: Unable to process command '::set-env name=DOC_TARGET::axi_to_mem' successfully.
Error: The `set-env` command is disabled. Please upgrade to using Environment Files or opt into unsecure command execution by setting the `ACTIONS_ALLOW_UNSECURE_COMMANDS` environment variable to `true`. For more information see: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/

https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/

Vivado simulator 2020.1: axi_lite_xbar: segmentation fault

I tried to simulate axi_lite_xbar with Xilinx VIP using the Vivado simulator.
during the xelab stage I got a segmentation fault, so I started to comment out sections of code.

I found out commenting out the instance of axi_lite_to_axi was kind of enough to get the xelab to not crash.
https://github.com/pulp-platform/axi/blob/master/src/axi_lite_xbar.sv#L165-L180

The converter itself does not have much code, and commenting it out did not help. So I started commenting out ports (both in the module and at the instance).
https://github.com/pulp-platform/axi/blob/master/src/axi_lite_to_axi.sv#L26-L27
Now I got an error I can not explain yet:

Starting static elaboration
Pass Through NonSizing Optimizer
ERROR: [VRFC 10-3814] value of 'req_lite_t' depends on itself [.../axi/src/axi_lite_to_axi.sv:19]
ERROR: [VRFC 10-3814] value of 'resp_lite_t' depends on itself [.../axi/src/axi_lite_to_axi.sv:20]
ERROR: [XSIM 43-3322] Static elaboration of top level Verilog design unit(s) in library work failed.

I tried to remove the default value of the parameter but I only got 2 extra warnings for the missing default value.

WORKAROUND: I renamed the two parameters by appending 1 at the, end and now xelab seems to get through.

I did not try to debug this further but I can speculate.
A. There is something globally defined with the same name as the parameter.
B. Vivado has some issue properly separating namespaces.

I was also compiling some VHDL code in the same project (actually just a barebone shell script).
I commented out the xvhdl command to avoid the VHDL namespace but it did affect the segmentation fault.

I do not have a relationship with Xilinx support right now, would you be able to file a bug report?
I also do not have the time to prepare a small example right now.

Replace assignments between AXI structs with calls to macros

Assignments between two struct variables, in the style of

assign req_a = req_b;
// or
always_comb begin
  req_a = req_b;
end

are problematic when the struct types of the two variables are defined differently: Because both sides of such an assignment are simply seen as a packed vector, the individual fields are not assigned correctly in this case. For request and response structs, this even includes handshaking signals, which might mess up the protocol.

While our modules are not designed for having structs with different widths at their slave and master ports (unless they are converting widths, of course), we should safeguard against such problems by always using macros to assign or set one struct to another.

Simulation Error

What simulation tool to use ? I use VCS there are some compile error:
Error-[UARC] Unsupported argument to randomize call
/nfs54/project/spiderman/zhuzhiqi/git/axi_pulp/axi/src/axi_test.sv, 1107
"w_beat"
Arg #1 of std::randomize "w_beat" is not integral or enum or array of
integral or enums
.......

Query: Max number of outstanding read requests

I am wondering what is the maximum number of outstanding read requests supported in the design?
Xilinx AXI interconnects limits to 32 for MMAP interface and I am looking for one that can support up to 256. The spec as it is does not have a limitation.

Naming Scheme for IDs and Wrappers

Can we get a small contribution/style section on how we decided to name ports, interface wrapper and parameters of the modules? What do you think?

Long critical path through the DW Converters

Atomics are at the critical path of the DW Converters.

Upon receiving an atomic request on the AW channel, the request is forwarded as a pseudo-AR request to one of the read up/downsizers, which will be responsible for handling the atomic responses on the R channel. The decision to forward the AW request to the read up/downsizers, the arbitration of which up/downsizer will handle the atomic request, and the logic of the up/downsizer upon receiving a new request, all that happens in a single cycle.

Pipelining this path might lead to max operating frequency improvements for the DW Converters, at the expense of lower performance for atomic operations.

axi_address_resolver relies on non-existing module

The axi_address_resolver component relies on the find_first_one component, which is not part of the repository. The axi_address_resolver component is used in axi_lite_xbar.sv.

Thus, when attempting to simulate using compile_vsim.sh / run_vsim.sh scripts, the simulation fails due to undefined module.

Add axi_cdc

Instantiate cdc_fifo_gray for each of the AXI channels (expose LOG_DEPTH parameter) and add similar header/documentation.

tb_axi_lite_regs: Random load collides with expected response

Hey!
In specific seed they value of rand_load in tests tb_axi_lite_regs causes assertion fail:

KERNEL: 1500000 Lite Master> Recieved read response from ADDR: 00000000 DATA: de01beef RESP: 0
KERNEL: Fatal Error: /home/tester/gitlab/axi/test/tb_axi_lite_regs.sv (124): Data is unexpected, should be axi_data_t'(64'hDEADBEEFDEADBEEF).

If we change seed, test works fine.

DWC (upsizer) stops accepting non-modifiable ARs

This affects the DWCs under development in #43 (unreleased). The problem can be reproduced within an internal project.

In isolation, it looks like the following does scenario not work:

  1. A master with a 64-bit data bus issues non-modifiable transaction of size 32 bit.
  2. An upsizer puts the transaction on a wider data bus (the transaction should still have size 32 bit).
  3. A downsizer puts the transaction on a 32-bit data bus.

Signals AR_READY / AW_READY on Master side

Hi all,

currently I do a simulation on your AXI XBAR with 2 masters and 2 slaves.

There I'm facing a problem with the signals A[R|W]_READY on master interfaces. At the start of the simulation they are '1' and they remain '1' during the simulation. The two slaves I wrote set their READY signals to '0' at the start of the simulation and behave correctly. The ready signals for the data and the WriteResponse channel behave correctly on master and slave side.

I ran the original TB tb_axi_xbar and there I saw the same behavior. Could you please provide help here?

I tried to attach 3 screenshots that describe the situation in detail. The waveforms are generated with the original testbench. Unfortunately I was not able to upload them. I will try later on.

Kind regards
Sebastian

axi_burst_splitter: Index out of bound warning.

When running scripts/run_vsim.sh tb_axt_to_axi_lite, there are excessive warings caused by axi_burst_splitter line 545, 551 and 559.
Not sure if ci picks up on this, as the run script runs through regardless.

Example warnings:

# ** Warning: (vsim-8233) Index xxxx into array dimension [9:0] is out of bounds.
#    Time: 75621 ns  Iteration: 4  Process: /tb_axi_to_axi_lite/i_dut/i_axi_to_axi_lite/i_axi_burst_splitter/i_axi_burst_splitter_ar_chan/i_axi_burst_splitter_counters/#ALWAYS#549 File: /scratch/msc19f10/axi/src/axi_burst_splitter.sv Line: 551
# ** Warning: (vsim-8233) Index xxxx into array dimension [9:0] is out of bounds.
#    Time: 75621 ns  Iteration: 4  Process: /tb_axi_to_axi_lite/i_dut/i_axi_to_axi_lite/i_axi_burst_splitter/i_axi_burst_splitter_ar_chan/i_axi_burst_splitter_counters/#ALWAYS#557 File: /scratch/msc19f10/axi/src/axi_burst_splitter.sv Line: 559
# 75633 axi_lite_rand_slave> Recv  W with DATA: f92db34a SRTB: 0
# 75635 axi_lite_rand_slave> Recv AR with ADDR: 17599778 PROT: 000
# ** Warning: (vsim-8233) Index xxxx into array dimension [9:0] is out of bounds.
#    Time: 75635 ns  Iteration: 4  Process: /tb_axi_to_axi_lite/i_dut/i_axi_to_axi_lite/i_axi_burst_splitter/i_axi_burst_splitter_ar_chan/i_axi_burst_splitter_counters/#ALWAYS#557 File: /scratch/msc19f10/axi/src/axi_burst_splitter.sv Line: 559
# ** Warning: (vsim-8233) Index xxxx into array dimension [9:0] is out of bounds.
#    Time: 75637 ns  Iteration: 2  Process: /tb_axi_to_axi_lite/i_dut/i_axi_to_axi_lite/i_axi_burst_splitter/i_axi_burst_splitter_ar_chan/i_axi_burst_splitter_counters/#ASSIGN#545 File: /scratch/msc19f10/axi/src/axi_burst_splitter.sv Line: 545

Edit: Seems that this has is caused by the id_queue.oup_data_o in axi_burst_splitter_counters indexing multiple arrays. On a glance seems to have no influence on functionality, but spams the simulation output.

DWCs

  • Stability?
  • TBs

axi_test.sv: random master freezing on read

When having the rand_axi_master configured as:

axi_test::rand_axi_master #(
      .AW ( 64   ),
      .DW ( 64 ),
      .IW  (    6 ),
      .UW ( 1   ),
      .TA ( tb_llc_pkg::appliSkew                           ),
      .TT ( tb_llc_pkg::clockPeriod - tb_llc_pkg::aquisSkew ),
      .MAX_READ_TXNS  ( 1          ),
      .MAX_WRITE_TXNS ( 5          )
      ) rand_axi_master;

Issuing the task:

rand_axi_master.run(5, 0, 64'h1000, 64'h10F0);

Then the Master performs the first Burst without issues. After recieving the last read beat of the first burst, the master transmitts the next AR vector, but then never sets its r_ready signal to 1.

Harmonize ports and parameters

Let us collect the changes required to harmonize ports and parameters and to minimize incompatibilities with EDA tools. Those changes will be breaking (as in "backwards-incompatible"), so let us make sure we get them right.

This is currently a draft and contributors are kindly asked to comment. Upon agreement, this information will be added to the Contribution Guidelines.

Preamble: The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

Parameters

Legal Types

Every parameter of a synthesizable module MUST be either:
(a) a type, or
(b) a (vector of) one of the following SystemVerilog types:

  • bit or logic, which MAY be signed (but are by default implicitly unsigned), or
  • byte, shortint, int, or longint, which MUST be followed by unsigned or signed, or

(c) a typedefed type of one of the types in (b).

In particular, structs and strings MUST NOT be used as parameter of a synthesizable module.

Rationale: Many tools do not properly implement complex types for parameters.

For non-synthesizable modules and classes, the key words MUST and MUST NOT in this section are relaxed to SHOULD and SHOULD NOT, respectively. (In particular, testbench modules MAY use time and string parameters.)

Signedness

If an integer parameter (i.e., byte, shortint, int, or longint) is not supposed to take negative values, it MUST be declared unsigned instead of signed.

Default Value

Every parameter MUST have a default value.

If possible, the default value SHOULD be a null value that is outside the legal range of the parameter (e.g., a signal width of zero). In this case, the module SHOULD contain an assertion to ensure that the parameter is set to a value other than the null value at instantiation.

Rationale: Many tools require parameters to have a default value, but in many cases a parameter that is not set at instantiation indicates an error that should be detected.

Derived Parameters

The parameter list of a module MUST NOT contain localparams. Rationale: Unsupported by some tools.

Instead, if the value of a parameter is derived from another parameter and should not be overridden at instantiation, the line above the derived parameter SHOULD be as follows:

/// Dependent parameter, DO NOT OVERRIDE!

Names

  • The name of a non-type parameter MUST be in UpperCamelCase.
    Rationale: style guide.
  • The name of a type parameter MUST be in lower_snake_case and end with _t.
    Rationale: style guide.
  • The name of a non-type parameter MUST NOT be prefixed with Axi.
    Example: A module with a parametrizable data width has a parameter named DataWidth, not AxiDataWidth.
    Rationale: Every module name starts with axi_ and prefixing parameters with Axi is redundant.
  • If a parameter only applies to one port, its name MUST start with the prefix of the port (converted to the casing dictated above and to singular if the port is an array) or with Num (see below) followed by the prefix of the port.
    Example: For a crossbar, the ID width of each of its slave ports (part of an array prefixed slv_ports_) would be given by a parameter named SlvPortIdWidth, and the request type of each of its slave ports would be given by a parameter named slv_port_axi_req_t.
  • Conversely, if a parameter applies to more than one port, its name MUST NOT start with the prefix of one of the ports.
  • If the name of a type parameter does not have a port-specific prefix, it MUST be prefixed with axi_.
    Rationale: Some tools do not properly scope type definitions, and adding a topic-specific prefix reduces the chance of type name collisions.
  • If a parameter defines the number of bits in a signal, its name SHOULD end with Width.
  • If a parameter defines a quantity other than bits in a signal, its name SHOULD contain Num followed by a noun in plural. No MUST NOT be used to denote a quantity parameter. (Rationale: easily mistaken for negation, e.g., "no registers").
  • If a parameter defines the maximum value of a quantity, its name SHOULD contain Max followed by a noun in plural.
  • The name of every parameter of a testbench module MUST start with Tb or tb_. The name of any parameter of a non-testbench module MUST NOT start with Tb or tb_.
    Rationale: The name of each parameter of a top-level module that is to be assigned a value when the simulator is invoked must be unique among all simulated modules; see #152 (comment).

Examples

A crossbar with multiple slv_ports and mst_ports could have the following among its parameters:

/// Number of slave ports of the crossbar
parameter int unsigned NumSlvPorts = 0,
/// Number of master ports of the crossbar
parameter int unsigned NumMstPorts = 0,
/// AXI address width
parameter int unsigned AddrWidth = 0,
/// AXI data width
parameter int unsigned DataWidth = 0,
/// AXI ID width at the slave ports
parameter int unsigned SlvPortIdWidth = 0,
/// Maximum number of in-flight transactions at each slave port
parameter int unsigned SlvPortMaxTxns = 0,
/// Maximum number of in-flight transactions at each master port
parameter int unsigned MstPortMaxTxns = 0,
/// AXI4(+ATOPs) request struct of each slave port
parameter type slv_port_axi_req_t = logic,
/// AXI4 response struct of each slave port
parameter type slv_port_axi_rsp_t = logic,
/// AXI4(+ATOPs) request struct of each master port
parameter type mst_port_axi_req_t = logic,
/// AXI4 response struct of each master port
parameter type mst_port_axi_rsp_t = logic,

Ports

  • Each input port MUST end with _i (or _ni if it is active-low).
  • Each output port MUST end with _o (or _no if it is active-low).
  • The name of each slave port MUST contain slv_port_ (or slv_ports_ if the port is an array).
  • The name of each master port MUST contain mst_port_ (or mst_ports_ if the port is an array).
  • The name of each request port MUST contain _req directly before the input/output suffix.
  • The name of each response port MUST contain _rsp directly before the input/output suffix.

Examples

A module with a single AXI-Lite slave port could contain in its inputs and outputs:

input  axi_lite_req_t slv_port_req_i,
output axi_lite_rsp_t slv_port_rsp_o,

A CDC from a src_clk_i to a dst_clk_i would contain in its inputs and outputs:

// Slave Port in Source Clock Domain
input  axi_req_t src_slv_port_req_i,
output axi_rsp_t src_slv_port_rsp_o,
// Master Port in Destination Clock Domain
output axi_req_t dst_mst_port_req_o,
input  axi_rsp_t dst_mst_port_rsp_i,

A crossbar with multiple slave and master ports would contain in its inputs and outputs:

// Slave Ports
input  slv_port_axi_req_t [NumSlvPorts-1:0] slv_ports_req_i,
output slv_port_axi_rsp_t [NumSlvPorts-1:0] slv_ports_rsp_o,
// Master Ports
output mst_port_axi_req_t [NumMstPorts-1:0] mst_ports_req_o,
input  mst_port_axi_rsp_t [NumMstPorts-1:0] mst_ports_rsp_i,

A protocol converter from AXI to AXI-Lite would contain in its inputs and outputs:

// AXI Slave Port
input  slv_port_axi_req_t slv_port_req_i,
output slv_port_axi_rsp_t slv_port_rsp_o,
// AXI-Lite Master Port
output mst_port_axi_lite_req_t mst_port_req_o,
input  mst_port_axi_lite_rsp_t mst_port_rsp_i,

Channel and Request/Response Types

In this section, X MUST be either axi or axi_lite in accordance with whether the type is part of full AXI or AXI-Lite.

  • A channel type MUST end with X_Y_t, where Y is one of aw, w, b, ar, or r and MUST correspond to the channel type.
  • A request type MUST end with X_req_t.
  • A response type MUST end with X_rsp_t.

Interfaces

  • This repository defines four interfaces: axi_if, axi_dv_if, axi_lite_if, and axi_lite_dv_if.
    Rationale for naming: compliant with Google Verible's interface-name-style and consistent with the name of types in the style guide we follow (which does not have rules for naming interfaces).
  • The modports are named slv_port (for a slave port modport), mst_port (for a master port modport), and mon_port (for an all-input monitor modport).
    Rationale: consistent with the naming of non-interface ports.
  • The non-dv interfaces MUST be synthesizable. The dv interfaces are used for design verification and MAY contain non-synthesizable code.
  • All parameters in an interface MUST obey the rules in the above Parameters section.
  • The name of each slave port interface MUST contain slv_port (or slv_ports if the interface port is an array).
  • The name of each master port interface MUST contain mst_port (or mst_ports if the interface port is an array).
  • Arrays of interfaces MUST be unpacked (i.e., dimensions after identifier). The dimensions MUST be in big-endian notation (e.g., [0:N-1]). Dimensions SHOULD be zero-based unless there are strong reasons against it. Zero-based dimensions SHOULD use the short [N] notation. There MUST NOT be a space between identifier and dimensions.

Examples

A crossbar (or rather, its _intf variant) with multiple slave and master ports would contain in its port list:

axi_if.slv_port slv_ports[NumSlvPorts],
axi_if.mst_port mst_ports[NumMstPorts],

axi_test_w_strobe calculation

axi_random_master
When doing unaligned access the bit mask for the strobes is not correct for transfers N>1.

// Determine strobe.
          w_beat.w_strb = '0;
          n_bytes = 2**aw_beat.ax_size;
          if (i == 0) begin
            begin_byte = addr % AXI_STRB_WIDTH;
          end else begin
            begin_byte = 0;
          end
          strb_mask = ((1'b1 << n_bytes) - 1) << begin_byte;
          rand_strb = $random();

random_axi_master issues WRAP transactions regardless of AXI_BURST_WRAP

When configured with AXI_ATOPS = 1'b1, the random_axi_master might issue WRAP transactions regardless of the value of AXI_BURST_WRAP.

axi/src/axi_test.sv

Lines 880 to 889 in b98dd67

// Determine `ax_burst`.
if (beat.ax_atop == axi_pkg::ATOP_ATOMICCMP) begin
// If the address is aligned to the total size of outgoing data, the burst type must be
// INCR. Otherwise, it must be WRAP. [E2-338]
beat.ax_burst = (beat.ax_addr % ((beat.ax_len+1) * 2**beat.ax_size) == 0) ?
axi_pkg::BURST_INCR : axi_pkg::BURST_WRAP;
end else begin
// Only INCR allowed.
beat.ax_burst = axi_pkg::BURST_INCR;
end

This creates an issue with modules that do not support WRAP transactions and use random_axi_master in their TBs. (The same thing can be said about BURST_INCR, although this is a more common case).

Questa Sim 2020.01 Regressions

Unfortunately, with the newest Questasim Version (Questa Sim-64 vsim 2020.1 Simulator 2020.01 Jan 28 2020) this

axi/src/axi_xbar.sv

Lines 217 to 222 in ec67055

initial begin : check_params
id_slv_req_ports: assert ($bits(slv_ports_req_i[0].aw.id ) == Cfg.AxiIdWidthSlvPorts) else
$fatal(1, $sformatf("Slv_req and aw_chan id width not equal."));
id_slv_resp_ports: assert ($bits(slv_ports_resp_o[0].r.id) == Cfg.AxiIdWidthSlvPorts) else
$fatal(1, $sformatf("Slv_req and aw_chan id width not equal."));
end

causes an internal error:

# ** Error:  src/axi/src/axi_xbar.sv(225): Questa has encountered an unexpected internal error: ../../src/vlog/vgentd.c(303). Please contact Questa support at http://supportnet.mentor.com/

Not sure how to solve this (and not suggesting to immediately react to it).

vsim 10.6c: axi_xbar: illegal port connection

Screenshot from 2020-12-20 13-55-52

** Error (suppressible): (vsim-3053) /home/fyp/pulpissimo/sim/../ips/axi/axi/src/axi_xbar.sv(162): Illegal output or inout port connection for port 'slv_resp_o'.
   Time: 0 ps  Iteration: 0  Instance: /tb_pulp/i_dut/soc_domain_i/pulp_soc_i/i_soc_interconnect_wrap/i_soc_interconnect/i_axi_xbar/i_xbar/gen_slv_port_demux[6]/i_axi_err_slv File: /home/fyp/pulpissimo/sim/../ips/axi/axi/src/axi_err_slv.sv

This error comes when I'm running the PULP-rt-example.
Thank you

axi_dw_downsizer: Response after transaction splitting

The downsizer might need to break an incoming AX request into several AX requests.

Currently, only the last response is forwarded back to the master. For example, if an incoming AW request is split into two, only the B beat corresponding to the second AW request will be forwarded to the master.

However, there is nothing special about the last response. It would be better to return the worst response between these corresponding to a split AX request. Xilinx does this, with the following precedence order: RESP_DECERR, RESP_SLVERR, RESP_OKAY.

DWC Slave Error on Burst Fixed with `len == 0`

This affects the DWCs under development in #43 (unreleased). The problem can be reproduced within an internal Ariane project.
As part of this I am using the DWC to connect APB peripherals as they have a data width of 32 instead of the 64 bit native to Ariane.
I have the issue that Ariane is issuing AXI transfers with len == 0 as FIXED:

    // address
    // in case of a single request or wrapping transfer we can simply begin at the address, if we want to request a cache-line
    // with an incremental transfer we need to output the corresponding base address of the cache line
    assign axi_req_o.ar.burst  = (rd_blen_i == 0)      ? 2'b00 :
                                                         2'b01;

However currently the DWC responds to all BURST_FIXED with a slave error even though it should be possible to let this type of transactions through, as they behave the same as if the burst type would be BURST_INCR.

        if (w_req_d.aw.burst inside {BURST_WRAP, BURST_FIXED}) begin
          w_state_d              = W_PASSTHROUGH;
          w_req_d.aw_throw_error = 1'b1         ;
        end

Wrong slave port is selected

Hi all,

I have a problem with the axi_xbar: I use a configuration with 4 masters and 2 slaves. The second master writes valid data to the interconnect and the data is confirmed by the slave, but by the wrong slave.

I write to address h'0080_0000 and expect the first slave to be connected but what I see is that data are going to slave 0 and in slave 0 the data are consumed, of course in a wrong way, but the bus transfer is correct.

I post my address map and the instantiation of the xbar, hopefully anybody has an idea:

    localparam int unsigned NoMasters   = 4; // How many Axi Masters there are
    localparam int unsigned NoSlaves    = 2; // How many Axi Slaves  there are

    // axi configuration
    localparam int unsigned AxiIdWidthMasters =  4;
    localparam int unsigned AxiIdUsed         =  4; // Has to be <= AxiIdWidthMasters
    localparam int unsigned AxiIdWidthSlaves  =  AxiIdWidthMasters + $clog2(NoMasters);
    localparam int unsigned AxiAddrWidth      =  32; // Axi Address Width
    localparam int unsigned AxiDataWidth      =  32; // Axi Data Width
    localparam int unsigned AxiStrbWidth      =  AxiDataWidth / 8;
    localparam int unsigned AxiUserWidth      =  5;
    // in the bench can change this variables which are set here freely
    localparam axi_pkg::xbar_cfg_t xbar_cfg = '{
    NoSlvPorts:         NoMasters,
    NoMstPorts:         NoSlaves,
    MaxMstTrans:        10,
    MaxSlvTrans:        6,
    FallThrough:        1'b0,
    LatencyMode:        axi_pkg::CUT_ALL_AX,
    AxiIdWidthSlvPorts: AxiIdWidthMasters,
    AxiIdUsedSlvPorts:  AxiIdUsed,
    AxiAddrWidth:       AxiAddrWidth,
    AxiDataWidth:       AxiDataWidth,
    // number of rules = number of slaves (one rule for each slave)
    NoAddrRules:        NoSlaves
    };

    // start_addr <= addr < end_addr => idx is the index of the slave to which the data goes
    localparam rule_t [xbar_cfg.NoAddrRules-1:0] AddrMap = '{
    '{idx: 32'd1, start_addr: 32'h0080_0000, end_addr: 32'h0080_1000},
    '{idx: 32'd0, start_addr: 32'h0000_0000, end_addr: 32'h0080_0000}
    };

The instantiation of the xbar is the following:

    // -------------------------------------------------------------------
    // -- AXI Intercon                                                  --
    // -------------------------------------------------------------------

    axi_xbar #(
        .Cfg          ( xbar_cfg ),
        .slv_aw_chan_t( aw_chan_mst_t ),
        .mst_aw_chan_t( aw_chan_slv_t ),
        .w_chan_t     (  w_chan_t     ),
        .slv_b_chan_t (  b_chan_mst_t ),
        .mst_b_chan_t (  b_chan_slv_t ),
        .slv_ar_chan_t( ar_chan_mst_t ),
        .mst_ar_chan_t( ar_chan_slv_t ),
        .slv_r_chan_t (  r_chan_mst_t ),
        .mst_r_chan_t (  r_chan_slv_t ),
        .slv_req_t    ( mst_req_t     ),
        .slv_resp_t   ( mst_resp_t    ),
        .mst_req_t    ( slv_req_t     ),
        .mst_resp_t   ( slv_resp_t    ),
        .rule_t       (rule_t         )
    ) i_xbar (
        .clk_i      ( sys_clk  ),
        .rst_ni     ( rst_n    ),
        .test_i     ( 1'b0     ),
        .slv_ports_req_i  ( masters_req  ),
        .slv_ports_resp_o ( masters_resp ),
        .mst_ports_req_o  ( slaves_req   ),
        .mst_ports_resp_i ( slaves_resp  ),
        .addr_map_i       ( AddrMap      ),
        .en_default_mst_port_i ( '0      ),
        .default_mst_port_i    ( '0      )
    );

In submodule i_xbar/gen_slv_port_demux[1]/i_axi_aw_decode/addr_map_i I can see that slave_aw_select is changing to one so I would expect that the correct master port of the intercon (corresponds to slave port in my design) is selected.

Thanks for helping!
Kind regards
Sebastian

axi_dw_downsizer: Support for FIXED bursts

The DW Downsizer currently does not support FIXED bursts.

If there is a need for downsizing, an incoming FIXED burst of length len should be converted into len+1 INCR bursts.

axi_dma

I can not find axi_dma module. Where can I find it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.