Skip to content

Latest commit

 

History

History
119 lines (89 loc) · 3.7 KB

File metadata and controls

119 lines (89 loc) · 3.7 KB

Previous | Index | Next

Basic concepts and examples

Introduction

The Alogic language is used for the description of digital circuits. In its simplest form, an Alogic design could be a network of FSMs, connected together (and/or connected to external sources) using input and output ports. In this way, systems such as pipelines or other complex modules can be built.

intro

An individual Alogic component is called a design entity (for example, a Finite State Machine or a Network). These are analogous to Verilog modules in that they can be instantiated inside other entities to build a design hierarchy. FSMs can be instantiated inside networks, which can in turn be instantiated inside other networks.

Control Units

Within an FSM, Alogic code is written as a series of sequential control units, with one control unit being executed per clock cycle. Transfer from one control unit to the next (achieved using Alogic keywords or events) is a change of state, and the design can branch out into different control units using branching statements. The states themselves are not mentioned within Alogic and instead are added by the compiler. As a result, FSMs are written in a locally linear way and appear similar to common software programming languages.

control-units

Alogic Prerequisites

The designer will need knowledge of:

  • Flow control
  • The difference between combinatorial and registered logic
  • Software languages such as C

Alogic Documentation

The Alogic documentation is a comprehensive guide to understanding and designing Alogic code. Amongst other details, it explains how to use different types of entities, how to connect them with ports, and the range of statements and data types that can be used.

Example FSM

The following code demonstrates an FSM with 3 states:

Fiddle with this code here.

fsm foo {
  void main() {
  
    // At this point we are in state 0
    u8 a = ...; // a is an unsigned 8-bit value
    u8 b = a + 7; // b is an unsigned 8-bit value
    
    // 'if' statements can occur within a Control Unit:
    if (a[0] == 1'b0) {
        a[0] = 1'b1;
    }
    // We are still in state 0
    
    fence; // This ends a Control Unit - the state will change.
    
    // We are now in state 1. Code continues to be executed linearly.
    b += 8'd1;
    
    if (b[2:0] == 3'b0) {
      doit(); // This function call ends the Control Unit
    } // An implicit else here also ends the Control Unit
    // We are now in state 2 or 3 depending on the outcome.
  }

  void doit() {
    ...
  }
}

Ports

Communication between entities happens through well defined interfaces called ports. A port carries some (usually registered) payload signals, and optionally some flow control signals with well-defined semantics.

A simple example of a module that, on every clock cycle, reads an 8 bit value from an input port using a valid-ready handshake and adds a quasi-static value to it is as follows:

Fiddle with this code here.

fsm add {
  in sync ready u8 p_in; // Input port, registered, with a valid-ready handshake.
  in u8 addend; // No flow control

  out sync ready u8 p_out; // Output port, registered, with a valid-ready handshake.

  void main() {
    u8 sum = p_in.read() + addend;
    p_out.write(sum);
    fence;
  }
}

Previous | Index | Next