diff --git a/hdl/src/wrapper_ahb_packet_constructor.sv b/hdl/src/wrapper_ahb_packet_constructor.sv new file mode 100644 index 0000000000000000000000000000000000000000..b0e450770983a4e9cfb87079519f8a270f00f2f4 --- /dev/null +++ b/hdl/src/wrapper_ahb_packet_constructor.sv @@ -0,0 +1,103 @@ +//----------------------------------------------------------------------------- +// SoC Labs AHB Packet Constructor +// 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_interface #( + //parameter for address width + parameter ADDRWIDTH=11, + parameter PACKETWIDTH=512 +)( + 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 Output Port + output logic [PACKETWIDTH-1:0] packet_data, + output logic packet_data_last, + output logic packet_data_valid, + input logic packet_data_ready + ); + + // 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; + + // 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) + ); + + wrapper_packet_construct #( + ADDRWIDTH, // Only half address map allocated to this device + 512 // Packet Width + ) u_wrapper_packet_construct ( + .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_valid (packet_data_valid), + .packet_data_ready (packet_data_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 new file mode 100644 index 0000000000000000000000000000000000000000..5f0747c718a410c016940fb0a14c5839790b82ce --- /dev/null +++ b/hdl/src/wrapper_ahb_reg_interface.sv @@ -0,0 +1,192 @@ +//----------------------------------------------------------------------------- +// SoC Labs AHB Wrapper Interface +// - 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) +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// The confidential and proprietary information contained in this file may +// only be used by a person authorised under and to the extent permitted +// by a subsisting licensing agreement from Arm Limited or its affiliates. +// +// (C) COPYRIGHT 2010-2011 Arm Limited or its affiliates. +// ALL RIGHTS RESERVED +// +// This entire notice must be reproduced on all copies of this file +// and copies of this file may only be made by a person if such person is +// permitted to do so under the terms of a subsisting license agreement +// from Arm Limited or its affiliates. +// +// SVN Information +// +// Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $ +// +// Revision : $Revision: 371321 $ +// +// Release Information : Cortex-M System Design Kit-r1p1-00rel0 +// +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// Abstract : AHB-lite example slave interface module. Transfer AHB-Lite BUS protocol to +// simple register read write protocol +//----------------------------------------------------------------------------- +module wrapper_ahb_reg_interface #( + //parameter for address width + parameter ADDRWIDTH=12) + ( + input logic hclk, // clock + input logic hresetn, // reset + + // AHB connection to master + 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, + + // Register interface + output logic [ADDRWIDTH-1:0] addr, + output logic read_en, + output logic write_en, + output logic [3:0] byte_strobe, + output logic [31:0] wdata, + input logic [31:0] rdata, + input logic wready, + input logic rready); + + // ---------------------------------------- + // Internal logics declarations + logic 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 update_read_req; // To update the read enable register + logic update_write_req; // To update the write enable register + + reg [ADDRWIDTH-1:0] addr_reg; // address signal, registered + reg read_en_reg; // read enable signal, registered + reg write_en_reg; // write enable signal, registered + + reg [3:0] byte_strobe_reg; // registered output for byte strobe + reg [3:0] byte_strobe_nxt; // next state for byte_strobe_reg + //----------------------------------------------------------- + // Module logic start + //---------------------------------------------------------- + + // Address signal registering, to make the address and data active at the same cycle + always_ff @(posedge hclk or negedge hresetn) + begin + if (~hresetn) + addr_reg <= {(ADDRWIDTH){1'b0}}; //default address 0 is selected + else if (trans_req) + addr_reg <= haddrs[ADDRWIDTH-1:0]; + end + + + // register read signal generation + assign update_read_req = ahb_read_req | (read_en_reg & hreadys); // Update read enable control if + // 1. When there is a valid read request + // 2. When there is an active read, update it at the end of transfer (HREADY=1) + + always_ff @(posedge hclk or negedge hresetn) + begin + if (~hresetn) + begin + read_en_reg <= 1'b0; + end + else if (update_read_req) + begin + read_en_reg <= ahb_read_req; + end + end + + // register write signal generation + assign update_write_req = ahb_write_req |( write_en_reg & hreadys); // Update write enable control if + // 1. When there is a valid write request + // 2. When there is an active write, update it at the end of transfer (HREADY=1) + + always_ff @(posedge hclk or negedge hresetn) + begin + if (~hresetn) + begin + write_en_reg <= 1'b0; + end + else if (update_write_req) + begin + write_en_reg <= ahb_write_req; + end + end + + // byte strobe signal + always_ff @(hsizes or haddrs) + begin + if (hsizes == 3'b000) //byte + begin + case(haddrs[1:0]) + 2'b00: byte_strobe_nxt = 4'b0001; + 2'b01: byte_strobe_nxt = 4'b0010; + 2'b10: byte_strobe_nxt = 4'b0100; + 2'b11: byte_strobe_nxt = 4'b1000; + default: byte_strobe_nxt = 4'bxxxx; + endcase + end + else if (hsizes == 3'b001) //half word + begin + if(haddrs[1]==1'b1) + byte_strobe_nxt = 4'b1100; + else + byte_strobe_nxt = 4'b0011; + end + else // default 32 bits, word + begin + byte_strobe_nxt = 4'b1111; + end + end + + always_ff @(posedge hclk or negedge hresetn) + begin + if (~hresetn) + byte_strobe_reg <= {4{1'b0}}; + else if (update_read_req|update_write_req) + // Update byte strobe registers if + // 1. if there is a valid read/write transfer request + // 2. if there is an on going transfer + byte_strobe_reg <= byte_strobe_nxt; + end + + //----------------------------------------------------------- + // Outputs + //----------------------------------------------------------- + // For simplify the timing, the master and slave signals are connected directly, execpt data bus. + assign addr = addr_reg[ADDRWIDTH-1:0]; + assign read_en = read_en_reg; + assign write_en = write_en_reg; + assign wdata = hwdatas; + assign byte_strobe = byte_strobe_reg; + + // Hreadyout Assignment + // If neither write_en or read_en, set hreadyouts to 0, if write or read, set to appropriate ready, if both, set to x + assign hreadyouts = write_en ? (read_en ? 1'bx : wready) : (read_en ? rready : 1'b1); + + assign hresps = 1'b0; // OKAY response from slave + assign hrdatas = rdata; + //----------------------------------------------------------- + //Module logic end + //---------------------------------------------------------- + + +endmodule + diff --git a/hdl/src/wrapper_ahb_interface.sv b/hdl/src/wrapper_ahb_to_vr_interface.sv similarity index 99% rename from hdl/src/wrapper_ahb_interface.sv rename to hdl/src/wrapper_ahb_to_vr_interface.sv index 2d3d77349f2485c265f672ff9aaca09452c6876c..71e2f6e875e425007f25bef9a4508515fd0fd8be 100644 --- a/hdl/src/wrapper_ahb_interface.sv +++ b/hdl/src/wrapper_ahb_to_vr_interface.sv @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// SoC Labs AHB Wrapper Interface +// SoC Labs AHB to Valid/Ready Wrapper Interface // - Adapted from ARM AHB-lite example slave interface module. // A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license. // @@ -35,7 +35,7 @@ // Abstract : AHB-lite example slave interface module. Transfer AHB-Lite BUS protocol to // simple register read write protocol //----------------------------------------------------------------------------- -module wrapper_ahb_interface #( +module wrapper_ahb_to_vr_interface #( //parameter for address width parameter ADDRWIDTH=12) ( diff --git a/hdl/src/wrapper_packet_construct.sv b/hdl/src/wrapper_packet_construct.sv index 487e66076ea8627cc4d20ec71dcf97dd267d6133..7d2f9447701da82690e1786f2e98e9cb6e7610fa 100644 --- a/hdl/src/wrapper_packet_construct.sv +++ b/hdl/src/wrapper_packet_construct.sv @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // SoC Labs Wrapper Files -// - Accelerator Packet Construction from AHB Write Transactions +// - Accelerator Packet Construction from Register Write Transactions // A joint work commissioned on behalf of SoC Labs; under Arm Academic Access license. // // Contributors @@ -33,19 +33,47 @@ module wrapper_packet_construct #( input logic packet_data_ready ); +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 + // 4KiB of Address Space for Accelerator (11:0) // Capture Address to be used for comparision to test for address jumping -logic [ADDRWIDTH-1:0] last_wr_addr; +logic [ADDRWIDTH-1:0] prev_wr_addr; + // Create Construction Buffer logic [PACKETWIDTH-1:0] const_buffer; logic const_buffer_last; +// Calculate which word in packet is to be written to/read from +// PacketSize/Register Data Width = number of Register Words per Packet +// Bytes Per Packet = Bytes per Word * Word per Packet +// example 512-bit packet, 32-bit register data +// addr[5:0] -> Number of bytes in packet +// addr[5:2] -> Number of 32-bit words in packet +// addr[5:2] * 32 -> bottom bit of 32-bit word in packet +// (addr[5:2] * 32) + 31 -> top bit of 32-bit word in packet logic [ADDRWIDTH-1:0] addr_top_bit; -assign addr_top_bit = (addr[5:2] * 32) - 1 + 32; +assign addr_top_bit = (addr[PACKETBYTEWIDTH-1:REGDBYTEWIDTH] * REGDWIDTH) + (REGDWIDTH - 1); + +// Check if current Register address is last word in packet +logic packet_last_word, prev_packet_last_word; +assign packet_last_word = &addr[PACKETBYTEWIDTH-1:REGDBYTEWIDTH]; +assign packet_last_word = &addr[PACKETBYTEWIDTH-1:REGDBYTEWIDTH]; + +// Packet Address - Address of Packet +logic [ADDRWIDTH-1:PACKETBYTEWIDTH] packet_addr, prev_packet_addr; +assign packet_addr = addr [ADDRWIDTH-1:PACKETBYTEWIDTH]; +assign prev_packet_addr = prev_wr_addr [ADDRWIDTH-1:PACKETBYTEWIDTH]; -// 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 +// Packet Last - When packet address all 1's +logic packet_addr_last, prev_packet_addr_last; +assign packet_addr_last = &packet_addr; +assign prev_packet_addr_last = &prev_packet_addr; + +// Write data out when either: +// - Word is last address of current packet +// - Address Moved to address of different packet // Write Condition always_ff @(posedge hclk or negedge hresetn) begin if (~hresetn) begin @@ -55,35 +83,45 @@ always_ff @(posedge hclk or negedge hresetn) begin packet_data_valid <= 1'b0; packet_data_last <= 1'b0; packet_data <= {PACKETWIDTH{1'b0}}; - last_wr_addr <= {ADDRWIDTH{1'b0}}; + prev_wr_addr <= {ADDRWIDTH{1'b0}}; end else begin // Handshake Output if (packet_data_ready && packet_data_valid) begin packet_data_valid <= 1'b0; end if (write_en) begin - // If not (awaiting handshake AND address generates new data payload) - if (!((packet_data_valid && !packet_data_ready) && (addr[5:2] == 4'hF))) begin + // If not (awaiting handshake on output AND address generates new data payload) + if (!((packet_data_valid && !packet_data_ready) && packet_last_word)) begin // Buffer Address for future Comparison - last_wr_addr <= addr; + prev_wr_addr <= addr; - // If 512 Word Address Changed, Clear Buffer - if (last_wr_addr[ADDRWIDTH-1:6] != addr [ADDRWIDTH-1:6]) const_buffer <= {PACKETWIDTH{1'b0}}; + // If Packet Address Changed - write out value in construction buffer + // - The output will get overwritten if the current address also causes generation of packet + if (packet_addr != prev_packet_addr) begin + // Produce Data Output + packet_data <= const_buffer; // Write out Previous value of construction buffer + // Calculate Last Flag on previous address + packet_data_last <= prev_packet_addr_last; + // Take Valid High + packet_data_valid <= 1'b1; + // Clear Construction Buffer + const_buffer <= {PACKETWIDTH{1'b0}}; + end // Write Word into Construction Buffer - const_buffer[addr_top_bit -: 32] <= wdata; + const_buffer[addr_top_bit -: REGDWIDTH] <= wdata; - // If last 32 bit word of 512 bit buffer - if (addr[5:2] == 4'hF) begin + // If last register word in packet construction buffer + if (packet_last_word) begin // Produce Data Output - packet_data <= {wdata,const_buffer[479:0]}; // Top word won't be in const_buffer + packet_data <= {wdata,const_buffer[(PACKETWIDTH-REGDWIDTH-1):0]}; // Top word won't be in const_buffer // - until next cycle to splice it in to out data combinatorially // Calculate Last Flag - packet_data_last <= (addr[ADDRWIDTH-1:6] == 5'h1F) ? 1'b1 : 1'b0; + packet_data_last <= packet_addr_last; // Take Valid High packet_data_valid <= 1'b1; // Reset Construction Buffer - const_buffer <= 512'd0; + const_buffer <= {PACKETWIDTH{1'b0}}; end end end @@ -91,19 +129,14 @@ always_ff @(posedge hclk or negedge hresetn) begin end // Read Condition -always_comb begin - if (read_en) begin - // Read appropriate 32 bits from buffer - wrapping behaviour - rdata = const_buffer[addr_top_bit -: 32]; - end else begin - rdata = 32'd0; - end -end +// Read appropriate Register Word from buffer - wrapping behaviour - otherwise read 0 +assign rdata = read_en ? const_buffer[addr_top_bit -: REGDWIDTH] : {REGDWIDTH{1'b0}}; // Register Ready Control -always_comb begin - rready = 1'b1; // Always able to read - may return 0 - wready = ~((packet_data_valid && ~packet_data_ready) && (((addr >> 2) & 11'hF) == 11'hF)); -end +// Always able to read +assign rready = 1'b1; +// Write Ready EXCEPT (when Packet waiting at output AND the current address triggers another packet to be generated at the output +// - when last word of packet +assign wready = ~((packet_data_valid && ~packet_data_ready) && packet_last_word); endmodule \ No newline at end of file diff --git a/hdl/src/wrapper_sha256_hashing_stream.sv b/hdl/src/wrapper_sha256_hashing_stream.sv index 8a2ba9811ac08faba8d051410dfb4e65470e807c..ae9fa89a8ffc642ebfd9a6fc23d6ec20bca10ec3 100644 --- a/hdl/src/wrapper_sha256_hashing_stream.sv +++ b/hdl/src/wrapper_sha256_hashing_stream.sv @@ -122,7 +122,7 @@ module wrapper_sha256_hashing_stream #( // Interface block to convert AHB transfers to Register transfers to engine input/output channels // engine Input/Output Channels - wrapper_ahb_interface #( + wrapper_ahb_to_vr_interface #( ADDRWIDTH ) u_wrapper_ahb_interface ( .hclk (HCLK), diff --git a/hdl/src/wrapper_vr_loopback.sv b/hdl/src/wrapper_vr_loopback.sv index c1785033720978d6d446e7da3a422246eee59b02..49bf64eef7919e4c95ada1d386e95fa0cf73e208 100644 --- a/hdl/src/wrapper_vr_loopback.sv +++ b/hdl/src/wrapper_vr_loopback.sv @@ -105,7 +105,7 @@ module wrapper_vr_loopback #( // Interface block to convert AHB transfers to Register transfers to engine input/output channels // engine Input/Output Channels - wrapper_ahb_interface #( + wrapper_ahb_to_vr_interface #( ADDRWIDTH ) u_wrapper_ahb_interface ( .hclk (HCLK),