diff --git a/flist/wrapper_ip.flist b/flist/wrapper_ip.flist index 94c2907d7c62fe3dd3ff0c2d8cb68932ce8d87e3..261a85d26d420dd541efefa124e460d0f8da520e 100644 --- a/flist/wrapper_ip.flist +++ b/flist/wrapper_ip.flist @@ -19,6 +19,11 @@ -y $(ACC_WRAPPER_DIR)/hdl/src/ +incdir+$(ACC_WRAPPER_DIR)/hdl/src/ +$(ACC_WRAPPER_DIR)/hdl/src/wrapper_ahb_packet_constructor.sv +$(ACC_WRAPPER_DIR)/hdl/src/wrapper_ahb_packet_deconstructor.sv + +$(ACC_WRAPPER_DIR)/hdl/src/wrapper_addr_calc.sv +$(ACC_WRAPPER_DIR)/hdl/src/wrapper_data_req.sv $(ACC_WRAPPER_DIR)/hdl/src/wrapper_ahb_reg_interface.sv $(ACC_WRAPPER_DIR)/hdl/src/wrapper_ahb_vr_interface.sv $(ACC_WRAPPER_DIR)/hdl/src/wrapper_packet_construct.sv diff --git a/hdl/src/wrapper_addr_calc.sv b/hdl/src/wrapper_addr_calc.sv new file mode 100644 index 0000000000000000000000000000000000000000..b91c39be935e2904b9eb673d3115d92f2073ad71 --- /dev/null +++ b/hdl/src/wrapper_addr_calc.sv @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// SoC Labs Relative Address Calculator +// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license. +// +// Contributors +// +// David Mapstone (d.a.mapstone@soton.ac.uk) +// +// Copyright 2023, SoC Labs (www.soclabs.org) +//----------------------------------------------------------------------------- +module wrapper_addr_calc #( + //parameter for address width + parameter ADDRWIDTH=11, + parameter PACKETWIDTH=256 +)( + // Number of Packets in Current Block + input logic [PACKETSPACEWIDTH:0] block_packet_count, + + // Start Address + output logic [ADDRWIDTH-1:0] block_addr +); + + localparam PACKETBYTES = (PACKETWIDTH+7)/8; // Number of Bytes in Packet + localparam PACKETBYTEWIDTH = $clog2(PACKETBYTES); // Number of Bits to represent Bytes in Packet + localparam PACKETSPACEWIDTH = ADDRWIDTH-PACKETBYTEWIDTH; // Number of Bits to represent all Packets in Address Space + + logic [ADDRWIDTH-1:0] block_byte_count; // Number of Bytes taken up by Block + logic [ADDRWIDTH:0] end_word_addr; // First Address at start of next region + logic [ADDRWIDTH:0] block_addr_ext; // Relative Address extended by 1 bit + + assign block_byte_count = block_packet_count * PACKETBYTES; + assign end_word_addr = {1'b1,{(ADDRWIDTH){1'b0}}}; + assign block_addr_ext = end_word_addr - block_byte_count; + assign block_addr = block_addr_ext[ADDRWIDTH-1:0]; + +endmodule \ No newline at end of file diff --git a/hdl/src/wrapper_ahb_packet_constructor.sv b/hdl/src/wrapper_ahb_packet_constructor.sv index b0e450770983a4e9cfb87079519f8a270f00f2f4..47546ac47491696915abb4660701471e950c5d9a 100644 --- a/hdl/src/wrapper_ahb_packet_constructor.sv +++ b/hdl/src/wrapper_ahb_packet_constructor.sv @@ -8,7 +8,7 @@ // // Copyright 2023, SoC Labs (www.soclabs.org) //----------------------------------------------------------------------------- -module wrapper_ahb_interface #( +module wrapper_ahb_packet_constructor #( //parameter for address width parameter ADDRWIDTH=11, parameter PACKETWIDTH=512 @@ -33,7 +33,10 @@ module wrapper_ahb_interface #( output logic [PACKETWIDTH-1:0] packet_data, output logic packet_data_last, output logic packet_data_valid, - input logic packet_data_ready + input logic packet_data_ready, + + // Data Request Signal + output logic data_req ); // Register Interface Connections @@ -46,6 +49,9 @@ module wrapper_ahb_interface #( logic wready; logic rready; + // Constructor Ready for more Data + logic constructor_ready; + // AHB Interface Instantiation wrapper_ahb_reg_interface #( ADDRWIDTH @@ -77,9 +83,31 @@ module wrapper_ahb_interface #( .rready (rready) ); + // Data Request Signal Generator + wrapper_data_req #( + ADDRWIDTH, // Only half address map allocated to this device + PACKETWIDTH // Packet Width + ) u_wrapper_data_req ( + .hclk (hclk), + .hresetn (hresetn), + + // AHB Address Phase Signaling + .hsels (hsels), + .haddrs (haddrs), + .htranss (htranss), + .hreadys (hreadys), + + // Engine Data Ready Signal + .constructor_ready (constructor_ready), + + // Data Request Signal + .data_req (data_req) + ); + + // Valid/Ready Packet Generator wrapper_packet_construct #( - ADDRWIDTH, // Only half address map allocated to this device - 512 // Packet Width + ADDRWIDTH, // Only half address map allocated to this device + PACKETWIDTH // Packet Width ) u_wrapper_packet_construct ( .hclk (hclk), .hresetn (hresetn), @@ -98,6 +126,9 @@ module wrapper_ahb_interface #( .packet_data (packet_data), .packet_data_last (packet_data_last), .packet_data_valid (packet_data_valid), - .packet_data_ready (packet_data_ready) + .packet_data_ready (packet_data_ready), + + // Data Request + .constructor_ready (constructor_ready) ); endmodule \ No newline at end of file diff --git a/hdl/src/wrapper_ahb_packet_deconstructor.sv b/hdl/src/wrapper_ahb_packet_deconstructor.sv new file mode 100644 index 0000000000000000000000000000000000000000..5afb2e0ae72f7a95b39be79152d7aa1d088fd603 --- /dev/null +++ b/hdl/src/wrapper_ahb_packet_deconstructor.sv @@ -0,0 +1,158 @@ +//----------------------------------------------------------------------------- +// SoC Labs AHB Packet Deconstructor +// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license. +// +// Contributors +// +// David Mapstone (d.a.mapstone@soton.ac.uk) +// +// Copyright 2023, SoC Labs (www.soclabs.org) +//----------------------------------------------------------------------------- +module wrapper_ahb_packet_deconstructor #( + //parameter for address width + parameter ADDRWIDTH=11, + parameter PACKETWIDTH=256 +)( + input logic hclk, // clock + input logic hresetn, // reset + + // AHB Input Port + input logic hsels, + input logic [ADDRWIDTH-1:0] haddrs, + input logic [1:0] htranss, + input logic [2:0] hsizes, + input logic hwrites, + input logic hreadys, + input logic [31:0] hwdatas, + + output logic hreadyouts, + output logic hresps, + output logic [31:0] hrdatas, + + // Valid/Ready Input Port + input logic [PACKETWIDTH-1:0] packet_data, + input logic packet_data_last, + input logic [PACKETSPACEWIDTH-1:0] packet_data_remain, // Number of remaining packets after this transfer + input logic packet_data_valid, + output logic packet_data_ready, + + // Data Request Signal + output logic data_req, + + // Start Read Address for Current Block + output logic [ADDRWIDTH-1:0] block_read_addr + ); + + localparam PACKETBYTEWIDTH = $clog2(PACKETWIDTH/8); // Number of Bytes in Packet + localparam PACKETSPACEWIDTH = ADDRWIDTH-PACKETBYTEWIDTH; // Number of Bits to represent all Packets in Address Space + + // Register Interface Connections + logic [ADDRWIDTH-1:0] addr; + logic read_en; + logic write_en; + logic [3:0] byte_strobe; + logic [31:0] wdata; + logic [31:0] rdata; + logic wready; + logic rready; + + // Deconstructor Ready for more Data + logic deconstructor_ready; + + // Number of Packets in Block + logic [PACKETSPACEWIDTH:0] block_packet_count; + + // AHB Interface Instantiation + wrapper_ahb_reg_interface #( + ADDRWIDTH + ) ahb_reg_interface_inst ( + .hclk (hclk), + .hresetn (hresetn), + + // Input slave port: 32 bit data bus interface + .hsels (hsels), + .haddrs (haddrs), + .htranss (htranss), + .hsizes (hsizes), + .hwrites (hwrites), + .hreadys (hreadys), + .hwdatas (hwdatas), + + .hreadyouts (hreadyouts), + .hresps (hresps), + .hrdatas (hrdatas), + + // Register Output interface + .addr (addr), + .read_en (read_en), + .write_en (write_en), + .byte_strobe (byte_strobe), + .wdata (wdata), + .rdata (rdata), + .wready (wready), + .rready (rready) + ); + + // Data Request Signal Generator + wrapper_data_req #( + ADDRWIDTH, // Only half address map allocated to this device + PACKETWIDTH // Packet Width + ) u_wrapper_data_req ( + .hclk (hclk), + .hresetn (hresetn), + + // AHB Address Phase Signaling + .hsels (hsels), + .haddrs (haddrs), + .htranss (htranss), + .hreadys (hreadys), + + // Constructor Data Ready Signal + .constructor_ready (deconstructor_ready), + + // Data Request Signal + .data_req (data_req) + ); + + // Relative Read Address Calculator + wrapper_addr_calc #( + ADDRWIDTH, // Only half address map allocated to this device + PACKETWIDTH // Packet Width + ) u_wrapper_addr_calc ( + // Address Interfaces + .block_packet_count (block_packet_count), + .block_addr (block_read_addr) + ); + + // Valid/Ready Packet Generator + wrapper_packet_deconstruct #( + ADDRWIDTH, // Only half address map allocated to this device + PACKETWIDTH // Packet Width + ) u_wrapper_packet_deconstruct ( + .hclk (hclk), + .hresetn (hresetn), + + // Register interface + .addr (addr), + .read_en (read_en), + .write_en (write_en), + .byte_strobe (byte_strobe), + .wdata (wdata), + .rdata (rdata), + .wready (wready), + .rready (rready), + + // Valid/Ready Interface + .packet_data (packet_data), + .packet_data_last (packet_data_last), + .packet_data_remain (packet_data_remain), + .packet_data_valid (packet_data_valid), + .packet_data_ready (packet_data_ready), + + // Block Packet Count + .block_packet_count (block_packet_count), + + // Data Request + .deconstructor_ready (deconstructor_ready) + ); +endmodule \ No newline at end of file diff --git a/hdl/src/wrapper_ahb_reg_interface.sv b/hdl/src/wrapper_ahb_reg_interface.sv index 4239ac64073e3b5da399765e7249dd0e1901a8fa..e4345b259af0668798fdd366976bb25a66c83a68 100644 --- a/hdl/src/wrapper_ahb_reg_interface.sv +++ b/hdl/src/wrapper_ahb_reg_interface.sv @@ -67,12 +67,13 @@ module wrapper_ahb_reg_interface #( // ---------------------------------------- // Internal logics declarations - logic trans_req= hreadys & hsels & htranss[1]; + logic trans_req; + assign trans_req = hreadys & hsels & htranss[1]; // transfer request issued only in SEQ and NONSEQ status and slave is // selected and last transfer finish - logic ahb_read_req = trans_req & (~hwrites);// AHB read request - logic ahb_write_req = trans_req & hwrites; // AHB write request + logic ahb_read_req;// AHB read request + logic ahb_write_req; // AHB write request logic update_read_req; // To update the read enable register logic update_write_req; // To update the write enable register @@ -86,6 +87,9 @@ module wrapper_ahb_reg_interface #( logic [1:0] haddrs_byte_sel; // Select which byte to enable logic haddrs_halfword_sel; // Select which byte to enable + assign ahb_read_req = trans_req & (~hwrites); + assign ahb_write_req = trans_req & hwrites; + assign haddrs_byte_sel = haddrs[1:0]; assign haddrs_halfword_sel = haddrs[1]; //----------------------------------------------------------- diff --git a/hdl/src/wrapper_data_req.sv b/hdl/src/wrapper_data_req.sv new file mode 100644 index 0000000000000000000000000000000000000000..abb50420ad47c68dfc76e01fed197a769c3d1d07 --- /dev/null +++ b/hdl/src/wrapper_data_req.sv @@ -0,0 +1,85 @@ +//----------------------------------------------------------------------------- +// SoC Labs AHB Wrapper Write Ready Generator +// - Adapted from ARM AHB-lite example slave interface module. +// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license. +// +// Contributors +// +// David Mapstone (d.a.mapstone@soton.ac.uk) +// +// Copyright 2023, SoC Labs (www.soclabs.org) +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// Abstract : Looks for last word address of packet during address phase +// to de-assert accelerator ready signal. +//----------------------------------------------------------------------------- +module wrapper_data_req #( + parameter ADDRWIDTH=11, + parameter PACKETWIDTH=512 +)( + input logic hclk, // clock + input logic hresetn, // reset + + // AHB connection to master (Address-phase signals only) + input logic hsels, + input logic [ADDRWIDTH-1:0] haddrs, + input logic [1:0] htranss, + input logic hreadys, + + // Constructor/Deconstructor Ready Signal + input logic constructor_ready, + + // Connection to wrapper + output logic data_req +); + +localparam REGDWIDTH = 32; // Register Data Width +localparam PACKETBYTEWIDTH = $clog2(PACKETWIDTH/8); // Number of Bytes in Packet +localparam REGDBYTEWIDTH = $clog2(REGDWIDTH/8); // Number of Bytes in Register Data Word + +logic trans_req; +assign trans_req = hreadys & hsels & htranss[1]; + +// Check if current address is last word in packet +logic packet_last_word; +assign packet_last_word = &haddrs[PACKETBYTEWIDTH-1:REGDBYTEWIDTH]; + +// If constructor_ready => data_req EXCEPT if current address is last address +logic constructor_ready_reg; +logic data_req_latched; + +always_ff @(posedge hclk or negedge hresetn) begin + if (~hresetn) begin + constructor_ready_reg <= 1'b0; + data_req_latched <= 1'b0; + end else begin + // Buffer engine ready signal to determine state change + constructor_ready_reg <= constructor_ready; + // Latch data request signal once seen last address of packet + if (trans_req && packet_last_word && constructor_ready) begin + // Latch data request signal + data_req_latched <= 1'b1; + // Unlatch when latched and data phase finished + end else if (data_req_latched && hreadys) begin + // Unlatch data request signal + data_req_latched <= 1'b0; + end + end +end + +always_comb begin + if (~constructor_ready_reg) begin + // If engine ready is transitioning from low to high + data_req = constructor_ready; + end else begin + // If seeing last word of packet address and valid transfer request + if ((trans_req && packet_last_word) || data_req_latched) begin + // Drop data request signal after address phase of last word in packet + data_req = 1'b0; + end else begin + // After data phase, take value of engine ready + data_req = constructor_ready; + end + end +end +endmodule \ No newline at end of file diff --git a/hdl/src/wrapper_packet_construct.sv b/hdl/src/wrapper_packet_construct.sv index 792b7c5c04c3c6e1306b385c59759b25eed1f36c..238b5eef30cce764cdeda5da79d3648ebd471ccc 100644 --- a/hdl/src/wrapper_packet_construct.sv +++ b/hdl/src/wrapper_packet_construct.sv @@ -30,7 +30,10 @@ module wrapper_packet_construct #( output logic [PACKETWIDTH-1:0] packet_data, output logic packet_data_last, output logic packet_data_valid, - input logic packet_data_ready + input logic packet_data_ready, + + // Data Input Request + output logic constructor_ready ); localparam REGDWIDTH = 32; // Register Data Width @@ -71,6 +74,9 @@ logic packet_addr_last, prev_packet_addr_last; assign packet_addr_last = &packet_addr; assign prev_packet_addr_last = &prev_packet_addr; +// Engine Ready Assignment +assign constructor_ready = packet_data_ready; + // Write data out when either: // - Word is last address of current packet // - Address Moved to address of different packet diff --git a/hdl/src/wrapper_packet_deconstruct.sv b/hdl/src/wrapper_packet_deconstruct.sv index cb3656d34147c7d9720953202a739913e7715c38..0a0b76299a529307a6fe5a2738236bd1382c1b77 100644 --- a/hdl/src/wrapper_packet_deconstruct.sv +++ b/hdl/src/wrapper_packet_deconstruct.sv @@ -27,15 +27,24 @@ module wrapper_packet_deconstruct #( output logic rready, // Valid/Ready interface - input logic [PACKETWIDTH-1:0] packet_data, - input logic packet_data_last, - input logic packet_data_valid, - output logic packet_data_ready + input logic [PACKETWIDTH-1:0] packet_data, + input logic packet_data_last, + input logic [PACKETSPACEWIDTH-1:0] packet_data_remain, // Number of remaining packets after this transfer + input logic packet_data_valid, + output logic packet_data_ready, + + // Number of Packets in Current + output logic [PACKETSPACEWIDTH:0] block_packet_count, + + output logic deconstructor_ready ); +localparam PACKETBYTEWIDTH = $clog2(PACKETWIDTH/8); // Number of Bytes in Packet +localparam PACKETSPACEWIDTH = ADDRWIDTH-PACKETBYTEWIDTH; // Number of Bits to represent all Packets in Address Space + // Create Deconstruction Buffer -// logic [PACKETWIDTH-1:0] deconst_buffer; logic [(PACKETWIDTH/32)-1:0][31:0] deconst_buf; +assign deconst_buf = packet_data; // Create Array to Flag which buffers have been read logic [(PACKETWIDTH/32)-1:0] deconst_buf_flag; @@ -53,37 +62,43 @@ logic deconst_buf_flag_reduced; assign deconst_buf_flag_reduced = &(deconst_buf_flag | (cur_deconst_buf_flag)); logic deconst_buf_valid; +assign deconstructor_ready = deconst_buf_valid; + +// Previous Packet Last +logic prev_packet_last; + // Dump data on one of two conditions // - An address ends [5:0] in 0x3C i.e. [5:2] == 0xF // - Address Moved to different 512 bit word // Write Condition always_ff @(posedge hclk or negedge hresetn) begin if (~hresetn) begin - // Reset Construction Buffer - deconst_buf <= {PACKETWIDTH{1'b0}}; // Reset Values + block_packet_count <= {(PACKETSPACEWIDTH+1){1'b0}}; packet_data_ready <= 1'b0; deconst_buf_valid <= 1'b0; deconst_buf_flag <= {(PACKETWIDTH/32){1'b0}}; + prev_packet_last <= 1'b1; end else begin - // If ready is low and theres no valid data in buffer, asser ready - if (!packet_data_ready && !deconst_buf_valid) begin - packet_data_ready <= 1'b1; - end - // Read Packet into Deconstruction Buffer if (packet_data_valid && packet_data_ready) begin - packet_data_ready <= 1'b0; - deconst_buf <= packet_data; + packet_data_ready <= 1'b0; + end + // If buffer isn't valid but valid data on input, assert buffer valid + if ((packet_data_valid && !packet_data_ready) && !deconst_buf_valid) begin deconst_buf_valid <= 1'b1; deconst_buf_flag <= {(PACKETWIDTH/32){1'b0}}; + packet_data_ready <= 1'b0; + // Update block_packet_count + block_packet_count <= prev_packet_last ? ({1'b0, packet_data_remain} + 'b1) : block_packet_count; end if (read_en) begin // Register which words in the Deconstruction buffer have been read // Check if All Words have been Read - if (deconst_buf_flag_reduced && !(packet_data_valid && packet_data_ready)) begin + if (deconst_buf_flag_reduced && deconst_buf_valid) begin // Set Ready High To Get more Data into Buffer deconst_buf_valid <= 1'b0; packet_data_ready <= 1'b1; + prev_packet_last <= packet_data_last; end else begin deconst_buf_flag <= deconst_buf_flag | cur_deconst_buf_flag; end @@ -103,8 +118,8 @@ end // Register Ready Control always_comb begin - // Not Ready Out when waiting for Valid Data on Input - rready = ~packet_data_ready; + // Ready when data in deconstruction buffer + rready = deconst_buf_valid; // Write Ready always high but doesn't do anywthing wready = 1'b1; end diff --git a/set_env.sh b/set_env.sh index 9ee3471867b155ecf6a6d356ceb559d65bb0a0e3..b085f8b13a306c2862832310dd051017dd784b94 100644 --- a/set_env.sh +++ b/set_env.sh @@ -36,7 +36,7 @@ else # Source environment variables for all submodules for d in $ACC_WRAPPER_DIR/* ; do - if [ -f "$d/.git" ]; then + if [ -e "$d/.git" ]; then if [ -f "$d/set_env.sh" ]; then # If .git file exists - submodule source $d/set_env.sh