Skip to content
Juan Gonzalez-Gomez edited this page Dec 7, 2021 · 139 revisions

Contents

Introduction

In this collection you will find blocks for working with wires and buses of different sizes. Use it in your digital circuits for opensource FPGAs created with icestudio. All the blocks in this collection are passive: There are no active components (gates, flip-flips, etc), but just simple operations with wires (joining, spliting, rearranging...)

These are examples of some blocks of this collection:

Installation in Icestudio

Find information about collections and how to install them on this link: Installing the iceK collection in Icestudio. It was written for the iceK collection as an example. Use the repo of the icewires collection instead

Quick Download:

Using the collection

There are blocks for extracting bits from the Buses, adding wires to the Buses, reversing the wires in a bus, getting the sign bit, shifting right or left... All the operations are passive: they are implemented using only wires

Split: Extracting bits from a Bus

The Split blocks allow us to have access to the bits from an input Bus of N bits. It is easier to explain it by means of examples. In this picture the Split-1-3 block is shown:

The 4-bits input bus is divided into two sub-buses of sizes 1 and 3 bits. The 1-bit bus contains the most significant bit of the input Bus, and the 3-bits bus the less significant bits

This is another example: the Split-5-2 block. The 7-bits input bus is split into two sub-buses of 5 and 2 bits respectivelly

Other Split blocks have more than two outputs. For example, the Split 3-8-8 block has a 19-bits input bus that is split into three sub-buses of 3, 8 and 8 bits:

The Split blocks with the sufix -all mean that all the wires in the bus are accesible in their outputs. This is the 5-bits split-all block: There are 5 output wires

Example 1: Using the Bus-2-Split-all Block

This example is available on the File/Examples/03-Split/Alhmabra-II folder. The two buttons of the Alhambra-II board are shown on the LEDs 7 and 0 respectivelly. This functionality can be implemented in different ways. In this examples a 2-bits Bus Split-all block is used

The two buttons are read in a 2-bits Bus that is split into its two independent bits. The Most significant bit is shown on LED7 and the Less Significan Bit on the LED0

Example 2: Using the Split 1-4 block

In this example the Split-1-4 block is used for spliting a 5-bits constant into two sub-buses of sizes 1 and 4 bits. The MSB bit is shown on LED7 and the other 4 Less significant bits are shown on the LEDs 0,1,2 and 3

Implementation

As the Split blocks are foundamental, they all are implemented in Verilog (and not from other blocks), using assign statements

For example, the Split-1-4 block is implemented with the following verilog code, were i is the input bus and o0 and o1 the output buses:

assign o1 = i[4];
assign o0 = i[3:0];

You can double click on the block for displaying its implementation:

Join: Grouping bits into a Bus

The Join blocks allow us to group together input buses to form a bigger output Bus. They are the opposite to the Split blocks. In this picture the Join-1-3 block is shown:

Another example: The Join-5-2 Block. Two input buses of sizes 5 and 2 bits respectivelly are joined into a 7-bits output bus

This is the Join-3-8-8 Block, the oposite of the Split-3-8-8. The three input buses of sizes 3, 8 and 8 bits are joined to form a 19-bits output bus

The sufix -all is used for joining all the input wires into a Bus. For example, the bus 5 join-all block has 5 wires as inputs and a 5-bits output bus

Example 3: Using the Bus-2-Join-all Block

This example is available on the File/Examples/04-Join/Alhmabra-II folder. The two buttons of the Alhambra-II board are inserted into a 2-bits bus and then shown on the LEDs 7 and 0. This functionality can be implemented in different ways. In this examples a 2-bits Bus Join-all block is used

Example 4: Using the Join-1-4 block

In this example the Join-1-4 block is used for joining together a 4-bits constant and the SW1 button into a 5-bits bus. This 5-bits output bus is displayed on 5 LEDs

Implementation

As the Join blocks are foundamental, they all are implemented in Verilog (and not from other blocks), using assign statements

For example, the Join-1-4 block is implemented with the following verilog code, were i0 and i1 are the input sub-bus and o is the output bus:

assign o = {i1, i0};

You can double click on the block for displaying its implementation:

Wire/Bus: Auxiliary wires

Auxiliary wires are Blocks that act like a wire or a Bus. You can find them on the Wires menu. In this picture you can see the wire block along with the Bus-3 block

These two circuits just turn on a LED. In the first one the connection between the 1 constant bit and the LED is direct. In the second the wire block is used. But both circuito are equivalent. They do exactly the same, and consume exactly the same resources on the FPGA

So, if these circuits are equivalent, why using the wire/bus blocks?. For two main reasons:

  • Wiring simplification and fragmentation: Sometimes the wiring of our design could be complex and difficult for other to understand or modify. By means of the wire/bus blocks this wiring can be simplified and/or fragmented so that long wires are divided in different parts (and these parts can be deleted without having to draw again the whole wire). In this picture you can see an example in wich the constante 1 is connected to the LED, but the wire has been divided into three segments. These segments can be rewired and moved indepently, without affecting the others

  • Direct conection of an input label with an output label. The labels are used for connecting the blocks of our circuits without visible wires, making our design more clean. The labels can be connected only to blocks, but not between them. Sometimes we could need to connect an input label directly to an output label. It can be achieve by means of the wire/bus blocks. These two circuits are equivalent. A button is conected to a LED. In the first circuit, que connection is made using only the label xx. In the second, the label xx is connected to the label yy (for creating a kind of virtual wire) and then to the LED

Example 5: Connecting two buttons to two LEDs

In this example two buttons are connected to two LEDs by means of the Bus-2 block. Of course, this block is not necessary: the buttons can be connected directly to the LEDs. But this is just an example of use

Implementation

The wire and buses blocks are implemented in verilog using the assign statement:

assign o = i;

where o is the output wire/bus and i the input wire/bus

For example, in this picture the implementation of the Bus-2 block is shown:

Copy: Copying a wire N times

When a wire is conected to other, the bit on the first wire is also transmited on the second wire. For example, if we want to show the state of one button on 4 LEDs, all we need to do is to connect 4 wires from the button to each LED. The four wires carry the same bit

Instead of placing 4 independent wires, we can use the Copy-4 block:

Using this block, the previous circuit become this new one:

Example 6: Turning on 8 LEDs with one button

In this example a Copy-8 block is used for turning on the 8 LEDs when pressing the SW1 button

Implementation

The implementation is done by connecting the inputs with a Join block. For example, this is how the Copy-8 is implemented:

Sign: Getting the sign bit

The Most Signicant Bit of a signed number carries the sign bit: 0 means positivo, 1 means negative. This bit can be extracted easily by means of the Sign block. In this picture a Sign-int8 block is shown

The input is an 8 bits signed number. The output is the signed bit (the Most significant Bit). You can find more Sign blocks for diferent sizes of signed number: 2, 3, 4 bits.... on the Sign menu

Example 7: Showing the sign bit on a LED

In this example, the sign of an 8-bit number in displayed on the LED7

Implementation

The Sign block is implemented with a Split block which extracts the most significant bit and ignore the rest of the bits:

UINT: Extend unsigned int numbers

A given unsigned number of N bits is extended to a bigger size of N+K bits (K 0-bits are added as Most significant bits). For example, if the 2-bits number 11 is extended to 8 bits this is the result: the number 00000011. 6 zero-bits have been added to the left

In this example the input is a 2-bits number and the output the 8-bits extended number

Example 8: Showing the two buttons on 8 LEDs

The two buttons are grouped into a 2-bit number. This number is extended to 8 bits and shown on the LEDs

Implementation

This block is implemented using a Join block, for adding the necesary 0s as the Most significant bits

Reversal: Reversing the bits of a bus

The bits of the input number are mirrored. For example, the 4-bit number abcd is outputed as the dcba number

Example 9: Mirroring the bits of a number

In this example the bits of the number 1100 are reversal and shown on the LEDs. The number shown is 0011

Implementation

This is the implementation of the 4-bits reversal block:

Shift blocks

These are blocks for shifting the bits to the right or to the left. The two basic blocks just shift 1 bit. In this picture you can see the shift-left (SL1) and shift-right (SR1) blocks for 4-bits numbers:

Let's use this 4-bits number as an example: 1010 (Whish is 10 in decimal). When it is shifted 1 bit to the left and a 0 inserted as its Less significant bit (LSB), the 4-bits result is 0100. The previous MSB was 1

If the same number is shifted 1 bit to the right and a 0 inserted as it Most significant bit (MSB), the 4-bits result is 0101. The previous LSB was 0

Example 10: Shifting a 4-bits number to the right

In this example the 4-bit number 1100 is shifted 1 bit to the right (an a 0 inserted as the MSB). The result is displayed on the LEDs 0-3

Implementation

TODO

  • Shift right, shift-left

Collections

Clone this wiki locally