Skip to content

Package

Patrick Lehmann edited this page Mar 13, 2015 · 1 revision

Table of Content

<wiki:toc max_depth="3" />

VHDL Package

[https://code.google.com/p/picoblaze-library/source/browse/vhdl/pb.pkg.vhdl Browse Source Code]

This is the main package for all PicoBlaze related types and functions. All types in this package are prefixed with T_PB_ and all constants are prefixed with C_PB_.

Dependancies

This package requires common packages from STD and IEEE as well as three core packages from [PoC PoC].

use     STD.TextIO.all;
        
library IEEE;
use     IEEE.NUMERIC_STD.all;
use     IEEE.STD_LOGIC_1164.all;
use     IEEE.STD_LOGIC_TEXTIO.all;
        
library PoC;
use     PoC.Utils.all;
use     PoC.Vectors.all;
use     PoC.Strings.all;

PicoBlaze instruction bus

The PicoBlaze has a 12 bit wide address and a 18 bit wide instruction bus.

subtype T_PB_ADDRESS      is STD_LOGIC_VECTOR(11 downto 0);
subtype T_PB_INSTRUCTION  is STD_LOGIC_VECTOR(17 downto 0);

PicoBlaze I/O-Bus

The following records combine all !PicoBlaze I/O port signals into two records: one from PB to the device and one from device to the PB. Additionally, two vectors are supplied to construct a group of these signals.

type T_PB_IOBUS_PB_DEV is record
  PortID         : T_SLV_8;
  Data           : T_SLV_8;
  WriteStrobe    : STD_LOGIC;
  WriteStrobe_K  : STD_LOGIC;
  ReadStrobe     : STD_LOGIC;
  Interrupt_Ack  : STD_LOGIC;
end record;
    
type T_PB_IOBUS_DEV_PB is record
  Data           : T_SLV_8;
  Interrupt      : STD_LOGIC;
  Message        : T_SLV_8;
end record;
    
type T_PB_IOBUS_PB_DEV_VECTOR is array(NATURAL range <>) of T_PB_IOBUS_PB_DEV;
type T_PB_IOBUS_DEV_PB_VECTOR is array(NATURAL range <>) of T_PB_IOBUS_DEV_PB

Address Mapping Data Structures

To accomplish a semi-automated bus wiring between the PB and it's devices, a data structure is needed. This structure holds all information for the automated wiring and debugging. Moreover, this structure can be exported to disk as supporting files for Xilinx ChipScope debugging (token files) or automated constant exports as *.psm include file(s).

The PicoBlaze has 3 address spaces:

  • the input address space of 256 ports each of 8 bit
  • the output address space of 256 ports each of 8 bit
  • the constant output address space of 16 ports each of 8 bit

Each I/O port is mapped to a register in a PicoBlaze device. it's possible to map multiple ports to one register. This allows OUTPUTK operations to write to normal OUTPUT affected registers.

At first a PortID to RegisterID mapping is declared:

type T_PB_PORTID_MAPPING is record
  PortID  : T_UINT_8;
  RegID   : T_UINT_8;
end record;
	
type T_PB_PORTID_MAPPING_VECTOR is array(NATURAL range <>) of T_PB_PORTID_MAPPING;
	
subtype T_PB_PORTID_KMAPPING         is T_PB_PORTID_MAPPING;
subtype T_PB_PORTID_KMAPPING_VECTOR  is T_PB_PORTID_MAPPING_VECTOR;

Secondly, a record is defined, which holds the address mapping for one !PicoBlaze device. It's assumed that input and output address spaces are overlapping, but constant output space can have different associations. This record stores also a long and a short device name and the interrupt ID (if used). Last but not least a bus affiliation can be set, which is needed for the semi automated wiring.

T_PB_ADDRESS_MAPPING_VECTOR stores the complete address mapping for one PicoBlaze.

type T_PB_ADDRESS_MAPPING is record
  DeviceName        : STRING(1 to C_PB_MAX_DEVICENAME_LENGTH);
  DeviceShort       : STRING(1 to C_PB_MAX_SHORTNAME_LENGTH);
    
  PortID_Mappings   : T_PB_PORTID_MAPPING_VECTOR(0 to C_PB_MAX_MAPPINGS - 1);
  MappingCount      : T_UINT_8;
    
  PortID_KMappings  : T_PB_PORTID_KMAPPING_VECTOR(0 to C_PB_MAX_KMAPPINGS - 1);
  KMappingCount     : T_UINT_8;
    
  InterruptID       : T_INT_8;
    
  BusAffiliation    : BIT_VECTOR(7 downto 0);
end record;
    
type T_PB_ADDRESS_MAPPING_VECTOR is array(NATURAL range <>) of T_PB_ADDRESS_MAPPING;

To reduce the memory footprint and synthesis time, 4 constants are defined to limit the memory consumption:

constant C_PB_MAX_MAPPINGS          : POSITIVE  := 16;
constant C_PB_MAX_KMAPPINGS         : POSITIVE  := 4;
constant C_PB_MAX_DEVICENAME_LENGTH : POSITIVE  := 64;
constant C_PB_MAX_SHORTNAME_LENGTH  : POSITIVE  := 16;</code>

Thirdly, some constants are pre-defined to ease the handling of this complex data
structure:

```vhdl
constant C_PB_PORTID_MAPPING_EMPTY  : T_PB_PORTID_MAPPING   := (PortID => 0, RegID => 0);
constant C_PB_PORTID_KMAPPING_EMPTY : T_PB_PORTID_KMAPPING  := (PortID => 0, RegID => 0);
constant C_PB_INTERRUPT_NONE        : T_INT_8               := -1;
	
constant C_PB_BUSAFFILATION_NONE    : T_PB_BUSAFFILATION    := x"01";
constant C_PB_BUSAFFILATION_ANY     : T_PB_BUSAFFILATION    := x"02";
constant C_PB_BUSAFFILATION_INTERN  : T_PB_BUSAFFILATION    := x"04";
constant C_PB_BUSAFFILATION_EXTERN  : T_PB_BUSAFFILATION    := x"08";
constant C_PB_BUS_INTERN            : T_PB_BUSAFFILATION    := C_PB_BUSAFFILATION_INTERN or C_PB_BUSAFFILATION_ANY;
constant C_PB_BUS_EXTERN            : T_PB_BUSAFFILATION    := C_PB_BUSAFFILATION_EXTERN or C_PB_BUSAFFILATION_ANY;

Note: Bus affiliations are one-hot encoded and buses are bit masks.

Address Mapping Constructors

The following functions (constructors) ease the creation of address mappings. The function takes the device name(s), a start address and a register count. Additionally a bus affiliation and an interrupt ID can be specified.

The overload accepts an additional OUTPUTK address mapping.

function pb_NewMapping(
  devName         : STRING;
  devShort        : STRING;
  startAddress    : NATURAL;
  addressCount    : POSITIVE;
  BusAffiliation  : BIT_VECTOR := C_PB_BUSAFFILATION_NONE;
  InterruptID     : INTEGER    := C_PB_INTERRUPT_NONE)
return T_PB_ADDRESS_MAPPING;
    		
function pb_NewMapping(
  devName         : STRING;
  devShort        : STRING;
  startAddress    : NATURAL;
  addressCount    : POSITIVE;
  KMappings       : T_PB_PORTID_KMAPPING_VECTOR;
  BusAffiliation  : BIT_VECTOR := C_PB_BUSAFFILATION_NONE;
  InterruptID     : INTEGER    := C_PB_INTERRUPT_NONE)
return T_PB_ADDRESS_MAPPING;

Example

constant ADDRESS_MAPPINGS : T_PB_ADDRESS_MAPPING_VECTOR := (
  -- AMID 0 - InterruptController            4..7
  pb_NewMapping(
    devName =>        "Interrupt Controller",
    devShort =>       "IntC",
    startAddress =>   4,
    addressCount =>   2,
    KMappings =>      (0 => (PortID => 4, RegID => 0), 1 => (PortID => 5, RegID => 1)),
    BusAffiliation => C_PB_BUS_INTERN,
    InterruptID =>    C_PB_INTERRUPT_NONE),
  -- AMID 1 - Multiplier                     12..15
  pb_NewMapping(
    devName =>        "Multiplier 16-bit",
    devShort =>       "Mult",
    startAddress =>   12,
    addressCount =>   4,
    BusAffiliation => C_PB_BUS_INTERN,
    InterruptID =>    C_PB_INTERRUPT_NONE),
  -- AMID 2 - General Purpose I/O             32..33
  pb_NewMapping(
    devName =>        "General Pupose I/O",
    devShort =>       "GPIO",
    startAddress =>   32,
    addressCount =>   2,
    KMappings =>      (0 => (PortID => 2, RegID => 0)),
    BusAffiliation => C_PB_BUS_INTERN,
    InterruptID =>    2),
  -- AMID 3 - UART                             40..41
  pb_NewMapping(
    devName =>        "Universal Asynchronous Receiver/Transmitter",
    devShort =>       "UART",
    startAddress =>   40,
    addressCount =>   2,
    KMappings =>      (0 => (PortID => 9, RegID => 1)),
    BusAffiliation => C_PB_BUS_EXTERN,
    InterruptID =>    3)
  );

Note: The indices of T_PB_ADDRESS_MAPPING_VECTOR are called 'address mapping ID' (AMID).

Accessing Address Mapping Properties

  • Return the address mapping ID (AMID) for a given short name: function pb_GetAMIdx(AddressMappingVector : T_PB_ADDRESS_MAPPING_VECTOR; DeviceShort : STRING) return NATURAL;

  • Has device i an interrupt ID (IntID):

    function pb_HasIntID(AddressMappingVector : T_PB_ADDRESS_MAPPING_VECTOR; index : NATURAL) return BOOLEAN;
  • Get the interrupt ID (IntID) for a given short name:

    function pb_GetIntID(AddressMappingVector : T_PB_ADDRESS_MAPPING_VECTOR; DeviceShort : STRING) return NATURAL;
  • Count all assigned interrupts:

    function pb_GetIntCount(AddressMappingVector : T_PB_ADDRESS_MAPPING_VECTOR) return NATURAL;

Helper Function for semi automated Wiring

Wiring Functions and Procedures

Example

https://picoblaze-library.googlecode.com/git-history/release/doc/Graphics/Graphics%20-%20BusInfrastructure.png

See also

Clone this wiki locally