-
Notifications
You must be signed in to change notification settings - Fork 0
Home
- Introduction
- Installation in Icestudio
- Using the collection
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:
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
- Download the ZIP file from the latest release
- ...or get the ZIP file with the latest changes from the main branch: iceWires-main.zip
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
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
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
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
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:
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
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
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
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:
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
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
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:
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:
In this example a Copy-8 block is used for turning on the 8 LEDs when pressing the SW1 button
The implementation is done by connecting the inputs with a Join block. For example, this is how the Copy-8 is implemented:
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
In this example, the sign of an 8-bit number in displayed on the LED7
The Sign block is implemented with a Split block which extracts the most significant bit and ignore the rest of the bits:
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
The two buttons are grouped into a 2-bit number. This number is extended to 8 bits and shown on the LEDs
This block is implemented using a Join block, for adding the necesary 0s as the Most significant bits
The bits of the input number are mirrored. For example, the 4-bit number abcd
is outputed as the dcba
number
In this example the bits of the number 1100
are reversal and shown on the LEDs. The number shown is 0011
This is the implementation of the 4-bits reversal block:
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
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
The implementation of the shift blocks is done using Split and Join blocks. This is the implementation for the 4-bits shift-right 1 block:
And this is the implementation for the 4-bits shift-left 1 block:
- Shift right, shift-left