adds AXI4/ACEL unaligned addr burst tests
This commit is contained in:
		| @@ -14,7 +14,7 @@ | ||||
| 				</extensions> | ||||
| 			</storageModule> | ||||
| 			<storageModule moduleId="cdtBuildSystem" version="4.0.0"> | ||||
| 				<configuration artifactName="${ProjName}" buildProperties="" description="" id="cmake4eclipse.mbs.toolchain.cmake.134761605" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="org.eclipse.cdt.build.core.emptycfg"> | ||||
| 				<configuration artifactName="${ProjName}" buildProperties="" description="" id="cmake4eclipse.mbs.toolchain.cmake.134761605" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=" parent="org.eclipse.cdt.build.core.emptycfg"> | ||||
| 					<folderInfo id="cmake4eclipse.mbs.toolchain.cmake.134761605.1159094612" name="/" resourcePath=""> | ||||
| 						<toolChain id="cmake4eclipse.mbs.toolchain.cmake.1883503430" name="CMake driven" superClass="cmake4eclipse.mbs.toolchain.cmake"> | ||||
| 							<targetPlatform id="cmake4eclipse.mbs.targetPlatform.cmake.1279728098" name="Any Platform" superClass="cmake4eclipse.mbs.targetPlatform.cmake"/> | ||||
|   | ||||
							
								
								
									
										2
									
								
								scc
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								scc
									
									
									
									
									
								
							 Submodule scc updated: e5439d3a32...bccc9269ff
									
								
							| @@ -24,7 +24,9 @@ void ABRThandler(int sig) { longjmp(abrt, 1); } | ||||
| int sc_main(int argc, char* argv[]) { | ||||
|     signal(SIGABRT, ABRThandler); | ||||
|     auto my_name = util::split(argv[0], '/').back(); | ||||
|     scc::init_logging(LogConfig().logLevel(getenv("SCC_TEST_VERBOSE") ? log::TRACE : log::FATAL).logAsync(false).msgTypeFieldWidth(35)); | ||||
|     auto level = getenv("SCC_TEST_VERBOSE"); | ||||
|     auto log_lvl = level ? static_cast<scc::log>(std::min(strtoul(level, nullptr, 10) + 4, 7UL)) : log::FATAL; | ||||
|     scc::init_logging(LogConfig().logLevel(log_lvl).logAsync(false).msgTypeFieldWidth(35)); | ||||
|     // create tracer if environment variable SCC_TEST_TRACE is defined | ||||
|     std::unique_ptr<scc::tracer> tracer; | ||||
|     if(auto* test_trace = getenv("SCC_TEST_TRACE")) { | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| project (axi4_pin_level) | ||||
|  | ||||
| add_executable(${PROJECT_NAME}  | ||||
| 	narrow_burst_test.cpp | ||||
| 	burst_test.cpp | ||||
| 	${test_util_SOURCE_DIR}/sc_main.cpp | ||||
| ) | ||||
| target_link_libraries (${PROJECT_NAME} PUBLIC test_util) | ||||
|   | ||||
| @@ -11,6 +11,55 @@ using tlm_gp_shared_ptr_vec = std::vector<tlm::scc::tlm_gp_shared_ptr>; | ||||
| 
 | ||||
| factory::add<testbench> tb; | ||||
| 
 | ||||
| //// DataTransfer()
 | ||||
| //// ==============
 | ||||
| // void DataTransfer(uint64_t Start_Address, unsigned axsize, unsigned axlen, unsigned Data_Bus_Bytes, axi::burst_e Mode, bool IsWrite) {
 | ||||
| //     auto Number_Bytes = 2u<<axsize;
 | ||||
| //     auto Burst_Length = axlen+1;
 | ||||
| //// Data_Bus_Bytes is the number of 8-bit byte lanes in the bus
 | ||||
| //// Mode is the AXI transfer mode
 | ||||
| //// IsWrite is TRUE for a write, and FALSE for a read
 | ||||
| // auto addr = Start_Address; // Variable for current address
 | ||||
| // auto Aligned_Address = (unsigned(addr/Number_Bytes) * Number_Bytes);
 | ||||
| // auto aligned = (Aligned_Address == addr); // Check whether addr is aligned to nbytes
 | ||||
| // auto dtsize = Number_Bytes * Burst_Length; // Maximum total data transaction size
 | ||||
| // auto Lower_Wrap_Boundary = 0ULL;
 | ||||
| // auto Upper_Wrap_Boundary = 0ULL
 | ||||
| // if(Mode == axi::burst_e::WRAP){
 | ||||
| //     Lower_Wrap_Boundary = (uint64_t(addr/dtsize) * dtsize);
 | ||||
| //     // addr must be aligned for a wrapping burst
 | ||||
| //     Upper_Wrap_Boundary = Lower_Wrap_Boundary + dtsize;
 | ||||
| // }
 | ||||
| // for(unsigned i=0; i<Burst_Length; ++i) {
 | ||||
| //     auto n = i+1;
 | ||||
| //     auto Lower_Byte_Lane = addr - (uint64_t(addr/Data_Bus_Bytes)) * Data_Bus_Bytes;
 | ||||
| //     if(aligned){
 | ||||
| //         auto Upper_Byte_Lane = Lower_Byte_Lane + Number_Bytes - 1;
 | ||||
| //     } else {
 | ||||
| //         auto Upper_Byte_Lane = Aligned_Address + Number_Bytes - 1
 | ||||
| //                 - (uint64_t(addr/Data_Bus_Bytes)) * Data_Bus_Bytes;
 | ||||
| //     }
 | ||||
| //     // Peform data transfer
 | ||||
| //     if(IsWrite)
 | ||||
| //         dwrite(addr, low_byte, high_byte);
 | ||||
| //     else
 | ||||
| //         dread(addr, low_byte, high_byte);
 | ||||
| //     // Increment address if necessary
 | ||||
| //     if(Mode != axi::burst_e::FIXED) {
 | ||||
| //         if(aligned){
 | ||||
| //             addr = addr + Number_Bytes;
 | ||||
| //             if(Mode == axi::burst_e::WRAP){
 | ||||
| //                     // WRAP mode is always aligned
 | ||||
| //                     if(addr >= Upper_Wrap_Boundary) addr = Lower_Wrap_Boundary;
 | ||||
| //             }
 | ||||
| //         } else {
 | ||||
| //             addr = Aligned_Address + Number_Bytes;
 | ||||
| //             aligned = true; // All transfers after the first are aligned
 | ||||
| //         }
 | ||||
| //     }
 | ||||
| // }
 | ||||
| // return;
 | ||||
| // }
 | ||||
| bool is_equal(tlm::tlm_generic_payload const& a, tlm::tlm_generic_payload const& b) { | ||||
|     auto ret = true; | ||||
|     ret &= a.get_command() == b.get_command(); | ||||
| @@ -39,7 +88,9 @@ tlm::tlm_generic_payload* prepare_trans(uint64_t start_address, unsigned addr_in | ||||
|     ext->set_size(scc::ilog2(width)); | ||||
|     sc_assert(len < (bus_cfg::BUSWIDTH / 8) || len % (bus_cfg::BUSWIDTH / 8) == 0); | ||||
|     auto length = (len * 8 - 1) / (8 * width); | ||||
|     if(width == (bus_cfg::BUSWIDTH / 8) && start_address % (bus_cfg::BUSWIDTH / 8)) | ||||
|     //    if(width == (bus_cfg::BUSWIDTH / 8) && start_address % (bus_cfg::BUSWIDTH / 8))
 | ||||
|     //        length++;
 | ||||
|     if(start_address % (bus_cfg::BUSWIDTH / 8) + width > (bus_cfg::BUSWIDTH / 8)) | ||||
|         length++; | ||||
|     ext->set_length(length); | ||||
|     // ext->set_burst(len * 8 > bus_cfg::buswidth ? axi::burst_e::INCR : axi::burst_e::FIXED);
 | ||||
| @@ -82,7 +133,7 @@ template <typename STATE> unsigned run_scenario(STATE& state) { | ||||
|         unsigned int StartAddr{0x0}; | ||||
|         for(int i = 0; i < state.NumberOfIterations; ++i) { | ||||
|             tlm::scc::tlm_gp_shared_ptr trans = | ||||
|                 prepare_trans<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 1); | ||||
|                 prepare_trans<testbench::bus_cfg>(StartAddr + (state.unaligned ? 2 : 0), 4, state.BurstLengthByte, state.BurstSizeBytes, 1); | ||||
|             trans->set_command(tlm::TLM_READ_COMMAND); | ||||
|             SCCDEBUG("run1") << "iteration " << i << " TX: " << *trans; | ||||
|             dut.intor_pe.transport(*trans, false); | ||||
| @@ -95,7 +146,7 @@ template <typename STATE> unsigned run_scenario(STATE& state) { | ||||
|         unsigned int StartAddr{0x2000}; | ||||
|         for(int i = 0; i < state.NumberOfIterations; ++i) { | ||||
|             tlm::scc::tlm_gp_shared_ptr trans = | ||||
|                 prepare_trans<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 2); | ||||
|                 prepare_trans<testbench::bus_cfg>(StartAddr + (state.unaligned ? 2 : 0), 4, state.BurstLengthByte, state.BurstSizeBytes, 2); | ||||
|             trans->set_command(tlm::TLM_WRITE_COMMAND); | ||||
|             randomize(*trans); | ||||
|             SCCDEBUG("run2") << "iteration " << i << " TX: " << *trans; | ||||
| @@ -109,7 +160,7 @@ template <typename STATE> unsigned run_scenario(STATE& state) { | ||||
|         unsigned int StartAddr{0x1000}; | ||||
|         for(int i = 0; i < state.NumberOfIterations; ++i) { | ||||
|             tlm::scc::tlm_gp_shared_ptr trans = | ||||
|                 prepare_trans<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 3); | ||||
|                 prepare_trans<testbench::bus_cfg>(StartAddr + (state.unaligned ? 2 : 0), 4, state.BurstLengthByte, state.BurstSizeBytes, 3); | ||||
|             trans->set_command(tlm::TLM_READ_COMMAND); | ||||
|             SCCDEBUG("run3") << "iteration " << i << " TX: " << *trans; | ||||
|             dut.intor_pe.transport(*trans, false); | ||||
| @@ -122,7 +173,7 @@ template <typename STATE> unsigned run_scenario(STATE& state) { | ||||
|         unsigned int StartAddr{0x3000}; | ||||
|         for(int i = 0; i < state.NumberOfIterations; ++i) { | ||||
|             tlm::scc::tlm_gp_shared_ptr trans = | ||||
|                 prepare_trans<testbench::bus_cfg>(StartAddr, 4, state.BurstLengthByte, state.BurstSizeBytes, 4); | ||||
|                 prepare_trans<testbench::bus_cfg>(StartAddr + (state.unaligned ? 2 : 0), 4, state.BurstLengthByte, state.BurstSizeBytes, 4); | ||||
|             trans->set_command(tlm::TLM_WRITE_COMMAND); | ||||
|             randomize(*trans); | ||||
|             SCCDEBUG("run4") << "iteration " << i << " TX: " << *trans; | ||||
| @@ -141,7 +192,8 @@ template <typename STATE> unsigned run_scenario(STATE& state) { | ||||
|     return cycles; | ||||
| } | ||||
| 
 | ||||
| void axi4_burst_alignment(bool pipelined_wrreq, bool write_bp) { | ||||
| void axi4_burst_alignment(bool pipelined_wrreq, bool write_bp, bool unaligned = false) { | ||||
|     SCCINFO(__FUNCTION__) << "starting with pipelined_wrreq=" << pipelined_wrreq << " and write_bp=" << write_bp; | ||||
|     struct { | ||||
|         unsigned int ResetCycles{4}; | ||||
|         unsigned int BurstLengthByte{16}; | ||||
| @@ -150,8 +202,10 @@ void axi4_burst_alignment(bool pipelined_wrreq, bool write_bp) { | ||||
|         std::unordered_map<unsigned, std::pair<tlm_gp_shared_ptr_vec, tlm_gp_shared_ptr_vec>> read_tx; | ||||
|         std::unordered_map<unsigned, std::pair<tlm_gp_shared_ptr_vec, tlm_gp_shared_ptr_vec>> write_tx; | ||||
|         unsigned resp_cnt{0}; | ||||
|         bool unaligned{false}; | ||||
|     } state; | ||||
| 
 | ||||
|     state.unaligned = unaligned; | ||||
|     auto& dut = factory::get<testbench>(); | ||||
|     dut.intor_bfm.pipelined_wrreq = pipelined_wrreq; | ||||
|     dut.tgt_pe.wr_data_accept_delay.set_value(write_bp ? 1 : 0); | ||||
| @@ -176,13 +230,24 @@ void axi4_burst_alignment(bool pipelined_wrreq, bool write_bp) { | ||||
|         auto const& recv_tx = e.second.second; | ||||
|         REQUIRE(send_tx.size() == recv_tx.size()); | ||||
|         for(auto i = 0; i < send_tx.size(); ++i) { | ||||
|             auto addr = send_tx[i]->get_address(); | ||||
|             if(addr % (testbench::bus_cfg::ADDRWIDTH / 8)) { | ||||
|                 CHECK(send_tx[i]->get_data_length() <= recv_tx[i]->get_data_length()); | ||||
|                 CHECK(send_tx[i]->get_byte_enable_length() <= recv_tx[i]->get_byte_enable_length()); | ||||
|                 // adjust the length of the read due to misalignment
 | ||||
|                 recv_tx[i]->set_data_length(send_tx[i]->get_data_length()); | ||||
|                 recv_tx[i]->set_byte_enable_length(send_tx[i]->get_byte_enable_length()); | ||||
|                 recv_tx[i]->set_streaming_width(send_tx[i]->get_streaming_width()); | ||||
|             } | ||||
|             REQUIRE(send_tx[i]->get_response_status() == tlm::TLM_OK_RESPONSE); | ||||
|             CHECK(is_equal(*send_tx[i], *recv_tx[i])); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void axi4_narrow_burst(bool pipelined_wrreq, bool write_bp) { | ||||
| void axi4_narrow_burst(bool pipelined_wrreq, bool write_bp, bool unaligned = false) { | ||||
|     SCCINFO(__FUNCTION__) << "starting with pipelined_wrreq=" << pipelined_wrreq << ", write_bp = " << write_bp | ||||
|                           << " and unaligned=" << unaligned; | ||||
|     struct { | ||||
|         unsigned int ResetCycles{4}; | ||||
|         unsigned int BurstLengthByte{16}; | ||||
| @@ -191,8 +256,10 @@ void axi4_narrow_burst(bool pipelined_wrreq, bool write_bp) { | ||||
|         std::unordered_map<unsigned, std::pair<tlm_gp_shared_ptr_vec, tlm_gp_shared_ptr_vec>> read_tx; | ||||
|         std::unordered_map<unsigned, std::pair<tlm_gp_shared_ptr_vec, tlm_gp_shared_ptr_vec>> write_tx; | ||||
|         unsigned resp_cnt{0}; | ||||
|         bool unaligned{false}; | ||||
|     } state; | ||||
| 
 | ||||
|     state.unaligned = unaligned; | ||||
|     auto& dut = factory::get<testbench>(); | ||||
|     dut.intor_bfm.pipelined_wrreq = pipelined_wrreq; | ||||
|     dut.tgt_pe.wr_data_accept_delay.set_value(write_bp ? 1 : 0); | ||||
| @@ -221,16 +288,32 @@ void axi4_narrow_burst(bool pipelined_wrreq, bool write_bp) { | ||||
| 
 | ||||
| TEST_CASE("axi4_burst_alignment", "[AXI][pin-level]") { axi4_burst_alignment(false, false); } | ||||
| 
 | ||||
| TEST_CASE("axi4_burst_alignment_unaligned_addr", "[AXI][pin-level]") { axi4_burst_alignment(false, false, true); } | ||||
| 
 | ||||
| TEST_CASE("axi4_narrow_burst", "[AXI][pin-level]") { axi4_narrow_burst(false, false); } | ||||
| 
 | ||||
| // TEST_CASE("axi4_narrow_burst_unaligned_addr", "[AXI][pin-level]") { axi4_narrow_burst(false, false, true); }
 | ||||
| 
 | ||||
| TEST_CASE("axi4_burst_alignment_with_bp", "[AXI][pin-level]") { axi4_burst_alignment(false, true); } | ||||
| 
 | ||||
| TEST_CASE("axi4_burst_alignment_with_bp_unaligned_addr", "[AXI][pin-level]") { axi4_burst_alignment(false, true, true); } | ||||
| 
 | ||||
| TEST_CASE("axi4_narrow_burst_with_bp", "[AXI][pin-level]") { axi4_narrow_burst(false, true); } | ||||
| 
 | ||||
| // TEST_CASE("axi4_narrow_burst_with_bp_unaligned_addr", "[AXI][pin-level]") { axi4_narrow_burst(false, true, true); }
 | ||||
| 
 | ||||
| TEST_CASE("axi4_burst_alignment_pipelined_write", "[AXI][pin-level]") { axi4_burst_alignment(true, false); } | ||||
| 
 | ||||
| TEST_CASE("axi4_burst_alignment_pipelined_write_unaligned_addr", "[AXI][pin-level]") { axi4_burst_alignment(true, false, true); } | ||||
| 
 | ||||
| TEST_CASE("axi4_narrow_burst_pipelined_write", "[AXI][pin-level]") { axi4_narrow_burst(true, false); } | ||||
| 
 | ||||
| // TEST_CASE("axi4_narrow_burst_pipelined_write_unaligned_addr", "[AXI][pin-level]") { axi4_narrow_burst(true, false, true); }
 | ||||
| 
 | ||||
| TEST_CASE("axi4_burst_alignment_pipelined_write_with_bp", "[AXI][pin-level]") { axi4_burst_alignment(true, true); } | ||||
| 
 | ||||
| TEST_CASE("axi4_burst_alignment_pipelined_write_with_bp_unaligned_addr", "[AXI][pin-level]") { axi4_burst_alignment(true, true, true); } | ||||
| 
 | ||||
| TEST_CASE("axi4_narrow_burst_pipelined_write_with_bp", "[AXI][pin-level]") { axi4_narrow_burst(true, true); } | ||||
| 
 | ||||
| // TEST_CASE("axi4_narrow_burst_pipelined_write_with_bp_unaligned_addr", "[AXI][pin-level]") { axi4_narrow_burst(true, true, true); }
 | ||||
							
								
								
									
										116
									
								
								tests/axi4_pin_level/waves.gtkw
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								tests/axi4_pin_level/waves.gtkw
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | ||||
| [*] | ||||
| [*] GTKWave Analyzer v3.3.118 (w)1999-2023 BSI | ||||
| [*] Wed Jan  8 16:33:12 2025 | ||||
| [*] | ||||
| [dumpfile] "/scratch/eyck/workarea/MINRES/SystemC-Components-Test/axi4_pin_level.fst" | ||||
| [dumpfile_mtime] "Wed Jan  8 16:32:32 2025" | ||||
| [dumpfile_size] 7261 | ||||
| [savefile] "/scratch/eyck/workarea/MINRES/SystemC-Components-Test/tests/axi4_pin_level/waves.gtkw" | ||||
| [timestart] 0 | ||||
| [size] 2560 1288 | ||||
| [pos] -1 -1 | ||||
| *-20.062529 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 | ||||
| [treeopen] testbench. | ||||
| [sst_width] 304 | ||||
| [signals_width] 243 | ||||
| [sst_expanded] 1 | ||||
| [sst_vpaned_height] 396 | ||||
| @28 | ||||
| testbench.clk | ||||
| testbench.rst | ||||
| @800200 | ||||
| -ar | ||||
| @28 | ||||
| testbench.ar_valid | ||||
| testbench.ar_ready | ||||
| @22 | ||||
| testbench.ar_addr[31:0] | ||||
| @28 | ||||
| testbench.ar_burst[1:0] | ||||
| @22 | ||||
| testbench.ar_cache[3:0] | ||||
| testbench.ar_id[3:0] | ||||
| testbench.ar_len[7:0] | ||||
| @28 | ||||
| testbench.ar_lock | ||||
| testbench.ar_prot[2:0] | ||||
| @22 | ||||
| testbench.ar_qos[3:0] | ||||
| testbench.ar_region[3:0] | ||||
| @28 | ||||
| testbench.ar_size[2:0] | ||||
| testbench.ar_user | ||||
| @1000200 | ||||
| -ar | ||||
| @800200 | ||||
| -r | ||||
| @28 | ||||
| testbench.r_valid | ||||
| testbench.r_ready | ||||
| testbench.r_last | ||||
| @22 | ||||
| testbench.r_data[63:0] | ||||
| testbench.r_id[3:0] | ||||
| @28 | ||||
| testbench.r_resp[1:0] | ||||
| testbench.r_trace | ||||
| testbench.r_user | ||||
| @1000200 | ||||
| -r | ||||
| @800200 | ||||
| -aw | ||||
| @28 | ||||
| testbench.aw_valid | ||||
| testbench.aw_ready | ||||
| @22 | ||||
| testbench.aw_id[3:0] | ||||
| testbench.aw_addr[31:0] | ||||
| @28 | ||||
| testbench.aw_burst[1:0] | ||||
| @22 | ||||
| testbench.aw_cache[3:0] | ||||
| testbench.aw_len[7:0] | ||||
| @28 | ||||
| testbench.aw_lock | ||||
| testbench.aw_prot[2:0] | ||||
| @22 | ||||
| testbench.aw_qos[3:0] | ||||
| testbench.aw_region[3:0] | ||||
| @28 | ||||
| testbench.aw_size[2:0] | ||||
| testbench.aw_user | ||||
| @1000200 | ||||
| -aw | ||||
| @800200 | ||||
| -w | ||||
| @29 | ||||
| testbench.w_valid | ||||
| testbench.w_ready | ||||
| testbench.w_ack | ||||
| @23 | ||||
| testbench.w_data[63:0] | ||||
| testbench.w_id[3:0] | ||||
| @29 | ||||
| testbench.w_last | ||||
| @23 | ||||
| testbench.w_strb[7:0] | ||||
| @29 | ||||
| testbench.w_trace | ||||
| testbench.w_user | ||||
| @1000200 | ||||
| -w | ||||
| @800200 | ||||
| -b | ||||
| @28 | ||||
| testbench.b_valid | ||||
| testbench.b_ready | ||||
| @22 | ||||
| testbench.b_id[3:0] | ||||
| @28 | ||||
| testbench.b_resp[1:0] | ||||
| testbench.b_trace | ||||
| testbench.b_user | ||||
| @1000200 | ||||
| -b | ||||
| [pattern_trace] 1 | ||||
| [pattern_trace] 0 | ||||
| @@ -2,12 +2,12 @@ | ||||
| #define SC_INCLUDE_DYNAMIC_PROCESSES | ||||
| #include <sysc/kernel/sc_simcontext.h> | ||||
| #endif | ||||
| #include <array> | ||||
| #include <catch2/catch_all.hpp> | ||||
| #include <factory.h> | ||||
| #include <scc/cci_param_restricted.h> | ||||
| #include <scc/utilities.h> | ||||
| #include <systemc> | ||||
|  | ||||
| using namespace sc_core; | ||||
|  | ||||
| struct top : public sc_core::sc_module { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user