Xilinx / Xilinx/libsystemctlm-soc

Axi2Tlm bridge does not support narrow bursts

Open
#26 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Verilog
Stars
307
Forks
93
PR merge metrics
No merged PRs in 30d

Description

GetData and FillData functions in axi2tlm bridge shall be modified as the following (a similar problem was reported by #20 as well):



        template<typename T1, typename T2>
        void FillData(T1& wdata, T2& wstrb) {
            unsigned char* gp_data = m_gp->get_data_ptr();
            unsigned char* be = m_gp->get_byte_enable_ptr();
            std::uint64_t address = m_gp->get_address();
            std::uint8_t numberBytes = m_genattr->get_burst_width();
            std::uint64_t alignedAddress;

            unsigned int lower_byte_lane;
            unsigned int upper_byte_lane;
            unsigned int i;

            alignedAddress = Align(address, numberBytes);

            if (m_burstType == AXI_BURST_FIXED) {
                lower_byte_lane = address - Align(address, DATA_BUS_BYTES);
                upper_byte_lane = alignedAddress + (numberBytes - 1) - Align(address, DATA_BUS_BYTES);

                for (i = 0; i < DATA_BUS_BYTES; i++) {
                    if (i >= lower_byte_lane && i <= upper_byte_lane) {
                        int firstbit = i * 8;
                        int lastbit = firstbit + 8 - 1;

                        if (wstrb.read().bit(i)) {
                            be[m_dataIdx] = TLM_BYTE_ENABLED;
                            gp_data[m_dataIdx] = wdata.read().range(lastbit, firstbit).to_uint();
                        } else {
                            be[m_dataIdx] = TLM_BYTE_DISABLED;
                        }

                        m_dataIdx++;
                    }
                }
            } else {
                if (m_beat == 1) {
                    lower_byte_lane = address - Align(address, DATA_BUS_BYTES);
                    upper_byte_lane = alignedAddress + (numberBytes - 1) - Align(address, DATA_BUS_BYTES);
                } else {
                    std::uint64_t address = alignedAddress + ((m_beat - 1) * numberBytes);

                    lower_byte_lane = address - Align(address, DATA_BUS_BYTES);
                    upper_byte_lane = lower_byte_lane + (numberBytes - 1);
                }

                assert(lower_byte_lane < DATA_BUS_BYTES);
                assert(upper_byte_lane < DATA_BUS_BYTES);

                // Set data
                for (i = 0; i < DATA_BUS_BYTES; i++) {
                    if (i >= lower_byte_lane && i <= upper_byte_lane) {
                        if (wstrb.read().bit(i)) {
                            int firstbit = i * 8;
                            int lastbit = firstbit + 8 - 1;

                            assert(m_dataIdx < m_gp->get_data_length());
                            be[m_dataIdx] = TLM_BYTE_ENABLED;
                            gp_data[m_dataIdx++] = wdata.read().range(lastbit, firstbit).to_uint();
                        } else {
                            be[m_dataIdx++] = TLM_BYTE_DISABLED;
                        }
                    }
                }

            }
        }

        template<typename T>
        void GetData(T& data) {
            unsigned char* gp_data = m_gp->get_data_ptr();
            std::uint64_t address = m_gp->get_address();
            std::uint8_t numberBytes = m_genattr->get_burst_width();
            std::uint64_t alignedAddress;
            unsigned int lower_byte_lane;
            unsigned int upper_byte_lane;
            unsigned int i;

            alignedAddress = Align(address, numberBytes);

            if (m_burstType == AXI_BURST_FIXED) {
                lower_byte_lane = address - Align(address, DATA_BUS_BYTES);
                upper_byte_lane = alignedAddress + (numberBytes - 1) - Align(address, DATA_BUS_BYTES);

                for (i = 0; i < DATA_BUS_BYTES; i++) {
                    if (i >= lower_byte_lane && i <= upper_byte_lane) {
                        int firstbit = i * 8;
                        int lastbit = firstbit + 8 - 1;

                        data.range(lastbit, firstbit) = gp_data[m_dataIdx++];
                    }
                }
            } else {
                if (m_beat == 1) {
                    lower_byte_lane = address - Align(address, DATA_BUS_BYTES);
                    upper_byte_lane = alignedAddress + (numberBytes - 1) - Align(address, DATA_BUS_BYTES);
                } else {
                    std::uint64_t address = alignedAddress + ((m_beat - 1) * numberBytes);

                    lower_byte_lane = address - Align(address, DATA_BUS_BYTES);
                    upper_byte_lane = lower_byte_lane + (numberBytes - 1);
                }

                // Set data
                for (i = 0; i < DATA_BUS_BYTES; i++) {
                    if (i >= lower_byte_lane && i <= upper_byte_lane) {
                        int firstbit = i * 8;
                        int lastbit = firstbit + 8 - 1;

                        data.range(lastbit, firstbit) = gp_data[m_dataIdx++];
                    }
                }
            }
        }

A similar might appear in tlm2axi bridges; however, I have not checked them yet.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Locate the axi2tlm bridge definitions of GetData and FillData, then review issue #20 for related context. Verify the bridge behavior for narrow bursts, including fixed and non-fixed bursts, and check whether the corresponding tlm2axi bridge needs the same treatment; the work is done when these cases are handled correctly and regressions are covered by the project’s existing checks.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.