FONT SIZE : AAA
Let’s skip to the always block. We will return to the lines before it shortly.
These blocks are where all the magic happens. They are where you can perform computation and read/write signals. The always block gets its name because it is always happening. When the tools see an always block, they need to generate a digital circuit that will replicate the behavior that the block describes.
Both Verilog and VHDL have their versions of the always block. In Verilog, they are also called always blocks. In VHDL, they are called processes.
Take a look at the always block in this example:
always {
reset_cond.in = ~rst_n; / input raw inverted reset signal
rst = reset_cond.out; / conditioned reset
led = 8h00; / turn LEDs off
spi_miso = bz; / not using SPI
spi_channel = bzzzz; / not using flags
avr_rx = bz; / not using serial port
}
The always block is an abstraction that allows us to create complicated designs without having to worry about exactly how it will be implemented. Inside an always block, statements that appear lower in the block have priority over earlier statements. This is kind of similar to programming, where if you write to a variable twice, the second write will be the one that persists, but this is just an abstraction. If a value is written twice in an always block, it is as if the first line doesn’t even exist. Take a look at the following example:
always {
led = 8h00; / turn LEDs off
led = 8hFF; / turn LEDs on
}
So what happens when this is synthesized? If you are thinking about this as code, you may be tempted to think that the LEDs would turn on and off continuously, but that’s not what happens. Remember, there is no processor running code; instead, a circuit will be made from this block. When the tools synthesize this, the first line will be ignored completely, and the LEDs will always be on. The led output would be hard‐ wired high. Although this example is trivial, and you would never write to the same signal sequentially like this, with conditional assignments (such as if statements) this becomes important.
Back to our design, the always block assigns values to six signals. Every output in a module must be assigned a value in all circumstances. Because the base project does nothing, and these signals are unused, they are assigned reasonable defaults.
Look at the first two lines in the always block:
reset_cond.in = ~rst_n; / input raw inverted reset signal
rst = reset_cond.out; / conditioned reset
On the first line, we are assigning a value to the input in of the module reset_cond . Modules, such as reset_cond , can be used inside other modules. This is similar to how you can call functions from other functions in code. However, unlike code, where you reuse the exact same instructions, the module will be duplicated in hard‐ ware each time you use it. This is why when you use a module it is called instantiating that module. You are creating another instance of it. We will get into more detail about how to instantiate a module in the next section, so don’t worry about these lines too much.
We are trying to connect the rst_n input, which corresponds to the reset button on the board, to reset_cond.in . Note that we actually connect ~rst_n to the input. The ~ operator inverts the signal (1 becomes 0, and 0 becomes 1). This makes it active high (1 means the button is pressed) instead of active low.
The second line connects the output out of reset_cond to the signal rst . The impor‐ tance of reset_cond will become clear later, but for now just know that it cleans up (synchronizes it to clk ) the button input, and rst will be 1 when the reset button is pressed and 0 when it isn’t. For this simple example, it isn’t needed, and we could use the rst_n input directly.
Take a look at the last four lines now:
led = 8h00; / turn LEDs off
spi_miso = bz; / not using SPI
spi_channel = bzzzz; / not using flags
avr_rx = bz; / not using serial port
On the first line, we assign the led output to all 0s. Remember from the port declara‐ tion that led is 8 bits wide. On this line we use 8h00 to make it clear we are setting all 8 bits to 0. We could have also just used the value 0 . This is because 0 would become 1d0 , but since led is 8 bits wide, it would be padded with 0s to match the width and would become equivalent to 8b00000000 (or 8h00 ).
The next three lines are assigning z to the signals. This is because these signals are outputs, so they need a value, but we aren’t using them in this example. Since they aren’t being used, the safest value is z . These signals connect to the microcontroller on the Mojo and are used to get access to the USB port and analog inputs.
When using x or z , constants won’t be padded with 0. For example, if you assign bx to a 4-bit signal, it will expand to 4bxxxx and not 4b000x . This is true only if the most significant bit is x or z . If you assign b0x to a 4-bit signal, it will expand to 4b000x .
If you look at the full always block, you’ll notice that there are no redundant assign‐ ments. When the design is synthesized, these values will be hardwired to the signals. The led output will be tied low, and the other outputs will be left floating (high impe‐ dance).
Manufacturer:Xilinx
Product Categories: CPLDs
Lifecycle:Active Active
RoHS:
Manufacturer:Xilinx
Product Categories: Programmable logic array
Lifecycle:Active Active
RoHS:
Manufacturer:Xilinx
Product Categories: CPLDs
Lifecycle:Unconfirmed -
RoHS:
Manufacturer:Xilinx
Product Categories: CPLDs
Lifecycle:Active Active
RoHS:
Manufacturer:Xilinx
Product Categories:
Lifecycle:Obsolete -
RoHS:
Support