Saturday 22 September 2012

Pics have Timers

PICs come with hardware counters know as timers. I have just been playing with its timer features using the PicKit3 demoboard. The diagram below is taken from the PIC tutorial I am following.


There are some interesting things to note:

  • The timer has a prescaler
  • TMR0IF is the output and it needs to be cleared when set.
  • There is a complex arrangement for reading TMR0H
The timer has a prescaler
The prescaler allows us to divide the timers clock. In the example below their are two line of code (one commented out) That set the value of the prescaler.

 // Init Timer
    INTCONbits.TMR0IF = 0;          // clear roll-over interrupt flag
    //T0CON = 0b00001000;             // no prescale - increments every instruction clock
    T0CON = 0b00000001;             // prescale 1:4 - four times the delay.
    TMR0H = 0;                      // clear timer - always write upper byte first
    TMR0L = 0;
    T0CONbits.TMR0ON = 1;           // start timer

 TMR0IF is the output and it needs to be cleared when set.
We need to clear the output of the timer before we start it. The counter can be started using T0CONbits.

There is a complex arrangement for reading TMR0H
The high byte of the timer is no directly accessible. It can only be accessed in conjunction with the lower bytes. To read the timer always read TMR0L first then TMR0H. To write to the timer always write to TMR0H first then followed by TMR0L.

Reference
MicroChip PICkit3 Debug Express, PIC18F45k20 - MPLAB C Lessons. 

Friday 21 September 2012

Rubik's Cube robot


I came across this video that uses iPhone and Lego Mindstorms to solve a Rubik's Cube.
Enjoy.


Wednesday 19 September 2012

Switch Input












This post looks at lesson 4 of the Pic tutorial.


/** D E F I N I T I O N S ****************************************************/
#define Switch_Pin      PORTBbits.RB0
#define DetectsInARow   5

The # define in the .h file can be used to define meaningful names to the SFR register.



#pragma udata   // declare statically allocated uinitialized variablesunsigned char LED_Display;  // 8-bit variable
#pragma code    // declare executable instructions
void main (void)
{
    unsigned char Switch_Count = 0;
    LED_Display = 1;            // initialize
    TRISD = 0b00000000;     // PORTD bits 7:0 are all outputs (0)     INTCON2bits.RBPU = 0; // enable PORTB internal pullups     WPUBbits.WPUB0 = 1; // enable pull up on RB0      ANSELH = 0x00;              // AN8-12 are digital inputs (AN12 on RB0)      TRISBbits.TRISB0 = 1;       // PORTB bit 0 (connected to switch) is input (1)
    while (1)
    {
        LATD = LED_Display;     // output LED_Display value to PORTD LEDs
        LED_Display <<= 1;      // rotate display by 1
        if (LED_Display == 0)
            LED_Display = 1;    // rotated bit out, so set bit 0

        while (Switch_Pin != 1);    // wait for switch to be released
        Switch_Count = 5;
        do
        { // monitor switch input for 5 lows in a row to debounce
            if (Switch_Pin == 0)
            { // pressed state detected                Switch_Count++;
            }
            else
            {
                Switch_Count = 0;
            }
            Delay10TCYx(25);    // delay 250 cycles or 1ms.        } while (Switch_Count < DetectsInARow);
    }
}

Some of the pins are shared with the analog input to the pic and hence need to be configured as digital. The C code above is also used to debonce the mechanical switch.

---

I decided to try my hand at some simple refactoring to make the code more readable.


/** V A R I A B L E S *************************************************/
#pragma udata   // declare statically allocated uinitialized variables
unsigned char LED_Display;  // 8-bit variable
unsigned char Switch_Count = 0;
/** D E C L A R A T I O N S *******************************************/
#pragma code    // declare executable instructions
void main (void)
{
    InitOutputs();
    InitInputs();
    while (1)
    {
        SetOutputLedAndRotate();
        DebounceSwitchDetect();
    }
}

void InitOutputs(void)
{
    LED_Display = 0b10101010;            // initialize
    TRISD = 0b00000000;     // PORTD bits 7:0 are all outputs (0)
}
 

void InitInputs(void)
{
    INTCON2bits.RBPU = 0; // enable PORTB internal pullups
WPUBbits.WPUB0 = 1; // enable pull up on RB0
    ANSELH = 0x00;              // AN8-12 are digital inputs (AN12 on RB0)
    TRISBbits.TRISB0 = 1;       // PORTB bit 0 (connected to switch) is input (1)
}


void SetOutputLedAndRotate(void)
{
     LATD = LED_Display;     // output LED_Display value to PORTD LEDs
     LED_Display <<= 1;      // rotate display by 1
     if (LED_Display == 0)
        LED_Display = 3;    // rotated bit out, so set bit 0
}
 
void DebounceSwitchDetect(void)
{
  while (Switch_Pin != 1);  // wait for switch to be released
        Switch_Count = 5;
        do
        { // monitor switch input for 5 lows in a row to debounce
            if (Switch_Pin == 0)
            { // pressed state detected
                Switch_Count++;
            }
            else
            {
                Switch_Count = 0;
            }
            Delay10TCYx(25);    // delay 250 cycles or 1ms.
        } while (Switch_Count < DetectsInARow);
}



Wednesday 12 September 2012

My Pic Microcontroller has some LEDs


Lesson 1: Hello LED
This blog post looks at doing nothing more that turning on and off the LEDs connected to port D of the PicKit3 demo board.






#pragma config FOSC = INTIO67
#pragma config WDTEN = OFF, LVP = OFF, MCLRE = OFF
#include "p18f45k20.h"
void main (void)
{
TRISD = 0b01111111; // PORTD bit 7 to output (0); bits 6:0 are inputs (1) LATDbits.LATD7 = 1; // Set LAT register bit 7 to turn on LED
while (1);
}

The TRISD variable is used to access the tri-state for I/O on port D. LATDbits.LATD7 is used to access the seventh bit of port D. The code below uses  LATD instead of LATDbits.LATD7 to achiveve the same affect.


#pragma config FOSC = INTIO67
#pragma config WDTEN = OFF, LVP = OFF, MCLRE = OFF
#include "p18f45k20.h"
void main (void)
{
TRISD = 0b01111111; // PORTD bit 7 to output (0); bits 6:0 are inputs (1)
        LATD = 0x80; while (1);
}

Lesson 2: BLINK LED
Configuration bits are used to set operating modes of enable disable different features of the Pic. The code below uses the configurations bits to set features such as the watch dog timer and the type of oscillator used.


#pragma config FOSC = INTIO67, FCMEN = OFF, IESO = OFF     // CONFIG1H
#pragma config PWRT = OFF, BOREN = SBORDIS, BORV = 30      // CONFIG2L
#pragma config WDTEN = OFF, WDTPS = 32768      // CONFIG2H
#pragma config MCLRE = OFF, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTC  // CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF    // CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF             // CONFIG5L
#pragma config CPB = OFF, CPD = OFF      // CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF    // CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF       // CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF   // CONFIG7L
#pragma config EBTRB = OFF   // CONFIG7H
#include "p18f45k20.h"
#include "delays.h"
void main (void)
{
TRISD = 0b01111111; // PORTD bit 7 to output (0) ; bits 6:0 are inputs (1) while (1)
{
LATDbits.LATD7 = ~LATDbits.LATD7; // toggle LATD
Delay1KTCYx(500); // Delay 50 x 1000 = 50,000 cycles; 200ms @ 1MHz } }


The Delay1KTCYx(500) instruction is used to create a delay. The delay in this example is 200 ms and  is calculated as follows:

Delay = (No of Cycles to execute an instruction/Frequency)  x Delay in thousands of clock cycles x 1000

Delay = (4/1MHz) x 50 x 1000 = 200ms.

Lesson 3: Rotate LED

#pragma udata (uninitialized data) and #pragma idata (initialized data) are used to allocate memory for static variables in the file register. #pragma code  is used to indicate a section of instructions and #pragma romdata is used for constant data stored in program memory.


/** C O N F I G U R A T I O N   B I T S ******/                                       
/** I N C L U D E S **********************/
/** V A R I A B L E S ********************/#pragma udata // declare statically allocated uninitialized variablesunsigned char LED_Number;  // 8-bit variable
/** D E C L A R A T I O N S *******************************************/// declare constant data in program memory starting at address 0x180#pragma romdata Lesson3_Table = 0x180
const rom unsigned char LED_LookupTable[8] = {0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80};
#pragma code    // declare executable instructions
void main (void)
{
    LED_Number = 0;            // initialize    TRISD = 0b00000000;     // PORTD bits 7:0 are all outputs (0)
    while (1)
    {
// use lookup table to output one LED on based on LED_Number value        LATD = LED_LookupTable[LED_Number];  
        LED_Number++;      // rotate display by 1
        if (LED_Number == 8)
            LED_Number = 0;    // go back to LED 0.
        Delay1KTCYx(50);    // Delay 50 x 1000 = 50,000 cycles; 200ms @ 1MHz    } }




Reference
MicroChip PICkit3 Debug Express, PIC18F45k20 - MPLAB C Lessons.



Tuesday 11 September 2012

I cant remember much about Pics


Harvard Architecture
The Microchip Pic microcontrollers are based on the Harvard Architecture. This means that the program and data memory are in separate address spaces i.e.  the each have their own address and data bus. In addition to program and data memory the stack also has its own dedicated memory which will allow 31 levels or subroutines.

Reset
On reset the address counter will be set to 0x000000. However the instruction placed at this address is normally a jump. The jump is used because the interrupt vectors sits at 0x000008 and 0x000018.

Memory Modes
Transparent to a C programmer the Pic can have two memory modes small and large and some areas program memory can be protected to keep your design from others eyes.

File Register
The Pic has between 4K and 8K of data memory, known as the File Register. The data is organised into 256k banks that can be accessed using a bank select register. There are areas in Bank0 and Bank15 that can be accessed without the need of swapping banks. This is known as Access Ram and contains the Special Function Registers. Again this is transparent to the C programmer.

Sunday 9 September 2012

Pacemaker Finished


I have just finished the Doulos (http://www.doulos.com) VHDL Tutorial called Pacemaker. The notes I made while working through the tutorial can be found in this blog and cover:
  1. VHDL State Encoding
  2. VHDL No Output Decoding Logic
  3. VHDL SM Separating Registers
  4. Explicit State Machine
  5. VHDL Variables & Registers
  6. VHDL The Five Process Styles
  7. VHDL FF using Wait Unitil
  8. Flip Flop with Enable
  9. VHDL Technology Dependent Components
  10. VHDL Asynchronous FF Reset
  11. VHDL Edge Triggered Flip Flop
  12. VHDL Transparent Latch
  13. VHDL Conversion Functions
  14. Synthesis if Arithmetic Operators
  15. VHDL Operator Overloading
  16. VHDL Std_Logic_Vector
  17. VHDL Constant
  18. VHDL Logical Operators
  19. VHDL Enumeration Types
  20. VHDL Equivalent Concurrent Statments
  21. VHDL Test Bench Clock
  22. VHDL While, Loop, Exit, Next
  23. VHDL For Loop
  24. VHDL Case Statment
  25. VHDL Incomplete Assignments
  26. VHDL IF Statment
  27. VHDL Variables
  28. VHDL Signal Assignment
  29. VHDL Test Vectors using Wait
  30. VHDL Wait
  31. VHDL Sensitivity List
  32. VHDL Process
  33. VHDL Configurations
  34. VHDL Test Bench
  35. VHDL STD_LOGIC
  36. VHDL Design Entity Referance
  37. VHDL Component Declaration and Instantiation
  38. VHDL Concurrent Signal Assignmants
  39. VHDL Signals
  40. VHDL Design Entity


VHDL State Encoding


type StateType is
         (Idle, Start, Stop, Clear);
signal State: StateType;


The states will be encoded as below. We can change the encoding by changing the order in the type statement.
Idle = 00
Start = 01
Stop = 01
Clear = 11

However some synthesis tools can be told to optimize the SM automatically. Do not turn on this option if you want to be in full control.

----
Unreachable states are created with the following type def.


type StateType is
         (One, Two, Three, Four, Five);

This is ok but if you want to specify what happens specify the dummy states you can create this as follows:

type StateType is
         (One, Two, Three, Four, Five,
          Dummy1, Dummy2, Dummy3);



Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

VHDL No Output Decoding Logic


architecture NoDecoding of AnotherFSM is
  constant Idle:  STD_LOGIC_VECTOR := "11";
  constant Start: STD_LOGIC_VECTOR := "01";
  constant Stop:  STD_LOGIC_VECTOR := "10";
  constant Clear: STD_LOGIC_VECTOR := "00";
  signal   State: STD_LOGIC_VECTOR(1 downto 0);
begin
  process
  begin
    wait until RISING_EDGE(Clock);
    if Reset = '0' then State <= Idle;
    else
      case State is
        when Idle   => State <= Start;
        when Start  => State <= Stop;
        when Stop   => State <= Clear;
        when Clear  => State <= Idle;
        when others => State <= Idle;
      end case;
    end if;
  end process;
  P <= State(1);
  Q <= State(0);
end;


In the above example we have coded the states.
The output is just a reference to the states.



Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

VHDL SM Separating Registers


architecture RegistersPlusLogic of FSM is
  type StateType is (Idle, Start, Stop, Clear);
  signal State: StateType;
begin
  Registers: process
  begin
    wait until RISING_EDGE(Clock);
    if Reset = '0' then
      State <= Idle;
    else
      State <= NextState;
    end if;
  end process;

  C_logic: process (State)
  begin
    if    State = Clear then NextState <= Idle;
                             F <= '1';
    elsif State = Idle  then NextState <= Start;
                             G <= '1';
    elsif State = Start then NextState <= Stop;
    else                     NextState <= Clear;
    end if;

  end process;
end;



Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

Explicit State Machine


architecture Explicit of FSM is
begin
  process
    type StateType is (Idle, Start, Stop, Clear);
    variable State: StateType;
  begin
    wait until RISING_EDGE(Clock);
    if Reset = '1' then
      State := Idle; F <= '0'; G <= '1';
    else
      case State is
        when Idle  => State := Start; G <= '0';
        when Start => State := Stop;
        when Stop  => State := Clear; F <= '1';
        when Clear => State := Idle;  F <= '0';
                                      G <= '1';
      end case;
    end if;
  end process;
end;


To avoid the outputs being registered we must split the VHDL into two processes.

 architecture SeparateDecoding of FSM is
  type StateType is (Idle, Start, Stop, Clear);
  signal State: StateType;
begin
  Change_state: process
  begin
    wait until RISING_EDGE(Clock);
    if    State = Clear or Reset = '1' then
                             State <= Idle;
    elsif State = Idle  then State <= Start;
    elsif State = Start then State <= Stop;
    else                     State <= Clear;
    end if;
  end process;

  Output: process (State)
  begin
    F <= '0'; G <= '0';
    if    State = Clear then F <= '1';
    elsif State = Idle  then G <= '1';
    end if;
  end process;

end;


Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

VHDL Variables & Registers


signal Reg: STD_LOGIC;
...

AND_REG: process
  variable V: STD_LOGIC; -- V is a wire.
begin
  wait until RISING_EDGE(Clock);
  V := '1';
  for I in 0 to 7 loop
    V := V and Input(I);
  end loop;
  Reg <= V; -- Reg is a FF
end process;


Reg is a signal so will always become a register.
V is assigned to 1 at the top of the file. We do not have to store the value of V between clock cycles so V is a wire.

---


Counter: process
  variable Count:
          STD_LOGIC_VECTOR(7 downto 0);
begin
  wait until RISING_EDGE(Clock);
  if Reset = '0' then
    Count := "00000000"; -- Count is a 8 FF's
  else
    Count := Count + '1';
  end if;
  Output <= Count(7); -- Output is one  FF. However some Synthis tools will merge this out.
end process;


---



process
begin
  wait until RISING_EDGE(Clock);
  Q <= Data;
  QB <= not Data;
end process;

The above will create two flip flops. This is corrected below.


process
begin
  wait until RISING_EDGE(Clock);
  Q <= Data;
end process;

QB <= not Q;


--

Note is we want to describe a shift register using a variable we need to move from the out



Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

Saturday 8 September 2012

VHDL The Five Process Styles

Style 1: Pure combinational logic


T1: process (All_Inputs)
begin
  ... Pure combinational logic
end process;

  • Rule: Complete sensitivity list 
  • Rule: All outputs completely assigned
  • Rule: No feedback.


---
Style 2: Transparent Latch


T2: process (All_Inputs)
begin
  if Enable = '1' then
    ... Transparent latches + logic
  end if;
end process;

The transparent latch has:

  • Rule: a single if statement with not else.
  • Rule: Complete sensitivity list 
  • Rule: No feedback.


---
Style 3: FF Using IF 


T3: process (Clock)
begin
  if RISING_EDGE(Clock) then
     ... Flipflops + logic
  end if;
end process;

  • Rule: The assignments must be syncronised to the clock edge
  • Rule: The must not be an ELSE statement
  • Rule: Check tool support of  RISING_EDGE
  • Rule: No statements must be placed after the END IF


--
Style 4: FF Using Wait


T4: process
begin
  wait until RISING_EDGE(Clock);
  ... Flipflops + logic
end process;


  • Rule: The assignments must be syncronised to the clock edge
  • Rule: Check tool support of  RISING_EDGE

--
Style 5: FF with Asynchronous Inputs


T5: process (Clock, Reset)
begin
  if Reset = '0' then
    ... Asynchronous actions
  elsif RISING_EDGE(Clock) then
    ... Flipflops + logic
  end if;
end process;



  • Rule: All asynchronous inputs must me added to the sensitivity list
  • Rule: You must check their value first before the clock check.
  • Rule: The assignments must be  syncronised to the clock edge
  • Rule: The must not be an ELSE statement
  • Rule: Check tool support of  RISING_EDGE
  • Rule: No statements must be placed after the END IF



Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

VHDL FF using Wait Unitil




  Another_Flipflop: process
  begin

    wait until Clock = '1'; -- must be the first statement in the process

    if Reset = '1' then
      Q <= '0';
    else
      Q <= D;
    end if;

  end process;


The process will run until it reaches the wait statement. then we assume the process is suspended until we get a   rising clock.


---

  Another_Flipflop: process
  begin
    wait until RISING_EDGE(Clock);

    if Reset = '1' then
      Q <= '0';
    else
      Q <= D;
    end if;
  end process;


We could use the rising_edge in the wait statement to create a clock.


Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

Flip Flop with Enable


process (Clock)
begin
  if RISING_EDGE(Clock) then

    if Reset = '1' then
      Q <= '0';

    elsif Enable = '1' then
      Q <= Data;
    end if;

  end if;
end process;


Depending on the technology the enable will either make use of the specific feature of an FPGA or will be implemented using a multiplexer.


Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

VHDL Technology Dependent Components


architecture A1 of Block1 is
  ...
  component GlobalResetBuffer
    port (Pin: in Std_logic);
  end component;

  signal Reset: Std_logic;
begin

  G: GlobalResetBuffer
                    port map (Reset);

  process (Clock, Reset)
  begin
    if Reset = '0' then
      Q <= '0';
    elsif RISING_EDGE(Clock) then
      Q <= Data;
    end if;
  end process;
  ...


Sometime we need to use specific areas of the FPGA. We can do this in VHDL for example we have specified a global reset above. However the VHDL will no longer be vendor independent.



Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

VHDL Asynchronous FF Reset


process (Clock, Reset)
begin

  if Reset = '0' then
    Count <= "00000000";

  elsif RISING_EDGE(Clock) then

    if Load = '1' then
      Count <= Data;
    else
      Count <= Count + '1';
    end if;

  end if;

end process;


This example show a flip flop with asynchronous reset.

---


...
signal Count :
          STD_LOGIC_VECTOR(7 downto 0);
begin
  process (Clock, Reset)
  begin
    if Reset = '0' then
      Count <= "00000000";
    elsif RISING_EDGE(Clock) then
      if Load = '1' then
        Count <= Data;  --load the counter 
      else
        Count <= Count + '1'; -- increment the counter
      end if;
    end if;
  end process;

Asynchronous and Synchronous parts of a eight bit counter with synchronous load.



Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

Friday 7 September 2012

Not Computer Games, FPGA Games!

I thought I had a clear idea in my head when to use a processor and when to us some kind of programmable logic device. However watching the videos below of how arcade games have been implemented using Altera FPGA's I am not so sure.




Thursday 6 September 2012

VHDL Edge Triggered Flip Flop


process (Clock)
begin

  if Clock'EVENT and Clock = '1' then

    Q0 <= D0;
    Q1 <= D1;

  end if;

end process;


The tick event attribute is used to create a latch controlled by a clock. The Clock'EVENT will infer a flip flop.

We could use a function in the 1164 packge to look at clock edges.


library IEEE;
use IEEE.STD_LOGIC_1164.all;

...

process (Clock)
begin

  if RISING_EDGE(Clock) then
    Q <= D;
  end if;

end process;

---



Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

VHDL Transparent Latch



  process (ENB, D)
  begin
    if ENB = '1' then
      Q <= D;
    end if;
  end process;

The value of Q will only change to Q if ENB is high. This is know as an incomplete assignment. Latch should no be used in FPGA because they need asynchronous feedback.

Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

VHDL Conversion Functions


We could not be allowed to assign and integer to a binary value.  But we can use a conversion function such as To_unsigned to allow us to achieve this.


use IEEE.NUMERIC_STD.all;

...

signal A: Unsigned(7 downto 0);
signal F: Unsigned(2 downto 0);

...

Priority_encoder: process (A)
begin
  F <= "000";
  for I in 0 to 7 loop
    if A(I) = '1' then
      F <= To_unsigned(I, 3);
      exit;
    end if;
  end loop;
end process;


---
The example below is used to assign an integer to a type STD_LOGIC.


use IEEE.NUMERIC_STD.all;

...

signal A: Unsigned(7 downto 0);
signal S: Unsigned(2 downto 0);
signal G: Std_logic;

...

Mux: G <= A(To_integer(S));


Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

Synthesis if Arithmetic Operators


F <= A + B;

This will synthesis to either:
1 - Non-optimal connection of FPGA cells or
2- Optimized structure of FPGA cells.

Some thisis acn take a + or - and map it directly to a standard block. But sometimes we need to use a vendor specific component our self's:

C1: ADDER8 port map (A,B,F)

The implementation depends on speed or size needed i.e. ripple carry adder v carry look-ahead adder.

Resource sharing can happen if the operators are on different paths of the same if statement.


process (A, B, C, D, K)
begin
  if K then
    Z <= A + B; -- 8 Bit
  else
    Z <= C + D;
  end if;
end process;


Share the same adder block.

However if the synthesis tool does not support resource sharing then the code could be rewritten to force the resource to be shared.


process (A, B, C, D, K)
  variable V1, V2 : ...
begin
  if K then
    V1 := A;
    V2 := B;
  else
    V1 := C;
    V2 := D;
  end if;
  Z <= V1 + V2;

end process;


Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

VHDL Operator Overloading



library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;

entity ADDER is
  port(A, B: in UNSIGNED(7 downto 0);
       SUM: out UNSIGNED(7 downto 0));
end;

architecture A1 of ADDER is
begin
  SUM <= A + B;
end;


The + and - can not be used with STD_LOGIC. We could use a vendor specific package that overloads these operators. However the IEEE.NUMERIC_STD package has created two new datatypes SIGNED and UNSIGNED. These do have overloaded operators for + and -.


Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

VHDL Std_Logic_Vector



signal
    A, B: STD_LOGIC_VECTOR(7 downto 0);
signal
    F: STD_LOGIC_VECTOR(15 downto 0);

F <= A & B; -- Concatenation

----



signal A, B, C: STD_LOGIC;
signal
    F: STD_LOGIC_VECTOR(3 downto 0);


F(3 downto 1) <= (A & B) & C; -- concatenate bit.


---
Signal Reg: STD_LOGIC_VECTOR(7 downto0);
Reg <= Reg(6 downto 0) & '0'; -- shift
Reg <= Reg(6 downto 0) & Reg(7); -- rotate

---

Reg <= Reg  sll '0'; -- shift VHDL 93 only
Reg <= Reg rol Reg(7); -- rotate VHDL 93 only


Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

Wednesday 5 September 2012

VHDL Constant


constant Active: Std_logic := '0';
constant SIZE: INTEGER := 16;
constant  ZERO: STD_LOGIC_VECTOR := "0000";


The value can not be changed.


Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

VHDL Logical Operators

AND
OR
NOT
NAND
NOR

XOR
XNOR


y <= a AND b;

The STD_LOGIC will synthesize to a single wire.



type STD_ULOGIC is (
        'U', -- Value at time 0
        'X',  - Strong  - Unknown
        '0', - Strong 
        '1',   - Strong 
        'Z', -- High impedance
        'W', - Week, Pull up resistor. - Unknown
        'L',  - Week, Pull up resistor.
        'H',  - Week, Pull up resistor.
        '-'); -- Don't care


case IP is
when "00" =>
  OP <= "0--1"; -- don't care
when "01" =>
  OP <= "1-0-";
when "10" =>
  OP <= "--10";
when others =>
  OP <= "101-";
end case;


---


type Opcode is (Add, Neg, Load,
                Store, Jmp, Halt);

signal S: Opcode := Halt;

variable
  V: Std_logic_vector(0 to 1) := "00";

initialize signals and variables using :=
Do not use initial values of synthesis. They are only used for simulation. 



Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

VHDL Enumeration Types



type Opcode is (Add, Neg, Load,
                Store, Jmp, Halt);

signal S: Opcode;


The names Add, Neg, Load, Store, Jmp, Halt do not represent any binary bit patterns.

---

architecture V1 of Ent is

  type Opcode is (Add, Neg, Load,
                  Store, Jmp, Halt);

  signal S: Opcode;
begin
  C1: Reg port map (..., S, ...);
  C2: Ctl port map (..., S, ...);
end;

The values will be encoded as a binary number 000,001,010,011 etc.

---

type BOOLEAN is (FALSE, TRUE); -- package standard

type BIT is ('0', '1'); -- package standard

type STD_ULOGIC is --- package standard logic
  ('U', 'X', '0', '1',
   'Z', 'W', 'L', 'H', '-');






Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

Tuesday 4 September 2012

VHDL Equivalent Concurrent Statments



architecture V2 of AOI is
  signal AB, CD, O: STD_LOGIC;
begin
  AB <= A and B after 2 NS;
  CD <= C and D after 2 NS;
  O <= AB or CD after 2 NS;
  F <= not O after 1 NS;
end V2;

Each of the concurrent statments are processes in their own right.

----

L: F <= A when S0 = '1' else
        B when S1 = '1' else
        C;

The above is equivalent to an if statement inside a process.


Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.

VHDL Test Bench Clock





ClockGenerator_1: process
begin
  for I in 1 to 1000 loop
    Clock <= '0';
    wait for 5 NS; 
    Clock <= '1';
    wait for 10 NS;
  end loop;
  wait; -- Remove this wait to loop for ever.
end process ClockGenerator_1;


The above example create 1000 clock pulses for a text bench. Frequency of clock is 1/(5ns+5ns).

---


ClockGenerator_2: process
begin
  while NOW < 15 US loop
    Clock <= '0';
    wait for 5 NS;
    Clock <= '1';
    wait for 10 NS;
  end loop;
  wait; -- Remove this wait to loop for ever.
end process ClockGenerator_2; 

The now is the current simulator time. The above example will create a clock for 15uS.

---


ClockGenerator_3: process
begin
  loop
    Clock <= '0';
    wait for 5 NS;
    Clock <= '1';
    wait for 10 NS;
    exit when NOW >= 15 US;
  end loop;
  wait;
end process ClockGenerator_3; 


Exit the loop when the stop time has been reached i.e NOW >= 15 US;



Reference

This blog post contains notes taken when working through the Doulos Pacemaker tutorial.   Any content copied from the tutorial has been reproduced with permission.  http://www.doulos.com.