// Example code for an M0 AHBLite System // Iain McNally // ECS, University of Soutampton // // This module is an AHB-Lite Slave containing a single read/write register // // Number of addressable locations : 1 // Size of each addressable location : 16 bits // Supported transfer sizes : Word, Halfword (preferred), Byte // Alignment of base address : Word aligned // // Address map : // Base addess + 0 : // Read LEDs register // Write LEDs register // module ahb_leds( // AHB Global Signals input HCLK, input HRESETn, // AHB Signals from Master to Slave input [31:0] HADDR, // With this interface HADDR is ignored input [31:0] HWDATA, input [2:0] HSIZE, input [1:0] HTRANS, input HWRITE, input HREADY, input HSEL, // AHB Signals from Slave to Master output [31:0] HRDATA, output HREADYOUT, //Non-AHB Signals output logic [15:0] LEDs ); // AHB transfer codes needed in this module localparam No_Transfer = 2'b0; //control signals are stored in registers logic write_enable, read_enable; logic [3:0] byte_select; //Generate the control signals in the address phase always_ff @(posedge HCLK, negedge HRESETn) if ( ! HRESETn ) begin write_enable <= '0; read_enable <= '0; byte_select <= '0; end else if ( HREADY && HSEL && (HTRANS != No_Transfer) ) begin write_enable <= HWRITE; read_enable <= ! HWRITE; byte_select <= generate_byte_select( HSIZE, HADDR[1:0] ); end else begin write_enable <= 0; read_enable <= 0; byte_select <= '0; end //Act on control signals in the data phase // write always_ff @(posedge HCLK, negedge HRESETn) if ( ! HRESETn ) LEDs <= 0; else if ( write_enable ) begin if( byte_select[0]) LEDs[ 7: 0] <= HWDATA[ 7: 0]; if( byte_select[1]) LEDs[15: 8] <= HWDATA[15: 8]; $display( "LED Update: ", HWDATA[15:0], " @", $time ); end //read // (output of zero when not enabled for read is not necessary but may help with debugging) assign HRDATA[ 7: 0] = ( read_enable && byte_select[0] ) ? LEDs[ 7: 0] : '0; assign HRDATA[15: 8] = ( read_enable && byte_select[1] ) ? LEDs[15: 8] : '0; assign HRDATA[23:16] = '0; assign HRDATA[31:24] = '0; //Transfer Response assign HREADYOUT = '1; //Single cycle Write & Read. Zero Wait state operations // decode byte select signals from the size and the lowest two address bits function logic [3:0] generate_byte_select( logic [2:0] size, logic [1:0] byte_adress ); logic byte3, byte2, byte1, byte0; byte0 = size[1] || ( byte_adress == 0 ); byte1 = size[1] || ( size[0] && ( byte_adress == 0 ) ) || ( byte_adress == 1 ); byte2 = size[1] || ( byte_adress == 2 ); byte3 = size[1] || ( size[0] && ( byte_adress == 2 ) ) || ( byte_adress == 3 ); return { byte3, byte2, byte1, byte0 }; endfunction endmodule