Difference between revisions of "Basic comps"
Line 6: | Line 6: | ||
# memory_bank_2r1w: 2 Read ports and 1 Write port. | # memory_bank_2r1w: 2 Read ports and 1 Write port. | ||
− | They both are memory elements (often mapped as a BRAM in Vivado), the first provides a simple interface and it is highly parametrizable: | + | They both are memory elements (often mapped as a BRAM in Vivado), the first provides a simple interface and it is highly parametrizable in size, number of element of each line, number of bits for element: |
parameter SIZE = 1024, | parameter SIZE = 1024, | ||
parameter ADDR_WIDTH = $clog2( SIZE ), | parameter ADDR_WIDTH = $clog2( SIZE ), | ||
Line 22: | Line 22: | ||
input logic [NB_COL*COL_WIDTH - 1:0] write_data, | input logic [NB_COL*COL_WIDTH - 1:0] write_data, | ||
− | In case of concurrent write and read on the address, the behaviour of the SRAM depends on the mode selected on its parameters: | + | The writing interface has a selective write_enable signal, this is a bitmap of which elements of the line are affected by the current operation. In case of concurrent write and read on the address, the behaviour of the SRAM depends on the mode selected on its parameters: |
parameter WRITE_FIRST = "TRUE" | parameter WRITE_FIRST = "TRUE" | ||
If "write_first" is enabled (true), the SRAM first stores the data in the memory then forwards the data just stored on the output signal. The other functionality mode is "read_first" (parameter WRITE_TRUE set to false), in this case, the module first fetch the old data from the memory and outputs it on the reading output signal, then stores into the memory the new data from the interface. | If "write_first" is enabled (true), the SRAM first stores the data in the memory then forwards the data just stored on the output signal. The other functionality mode is "read_first" (parameter WRITE_TRUE set to false), in this case, the module first fetch the old data from the memory and outputs it on the reading output signal, then stores into the memory the new data from the interface. | ||
+ | The second module (memory_bank_2r1w) provides a similar interface, although the memory_bank_2r1w has an extra reading port, obtained allocating two memory_bank_1r1w modules with their writing port connected together. In this way, each write operation is propagated to both elements, and the two memories are aligned in their content, thus the same reading operation performed on both fetches the same value. | ||
+ | |||
+ | == FIFO == | ||
+ | |||
+ | The sync_fifo module is extensively used in the design, it instantiates a parametrizable FIFO in term of width of the element and number of positions: | ||
− | + | parameter WIDTH = 64, | |
+ | parameter SIZE = 4, | ||
+ | |||
+ | Two parameters are control-oriented and widely used in the architecture: | ||
+ | |||
+ | parameter ALMOST_FULL_THRESHOLD = SIZE, | ||
+ | parameter ALMOST_EMPTY_THRESHOLD = 1 | ||
+ | |||
+ | Those set when the FIFO should signal to the back-pressure logic when it is full or empty: | ||
+ | |||
+ | output logic full, | ||
+ | output logic almost_full, | ||
+ | output logic empty, | ||
+ | output logic almost_empty, | ||
+ | |||
+ | In the default instantiation, the FIFO signals that it is full when the number of elements stored is equal to SIZE, ALMOST_FULL_THRESHOLD changes this rule, allowing the FIFO to signal the full condition in advance. The same for the empty condition. | ||
+ | |||
+ | Enqueuing an element in the FIFO can be easily done using the enqueue interface: | ||
+ | input enqueue_en, | ||
+ | input [WIDTH - 1:0] value_i, | ||
+ | |||
+ | When at least one element is pending in the FIFO, it is propagated on the value_o signal output and the empty signal is low. The dequeue_en signal pops the element from the FIFO: | ||
+ | input dequeue_en, | ||
+ | output [WIDTH - 1:0] value_o | ||
+ | |||
+ | Finally, the flush_en input signal empties the FIFO. Often used in case of rollbacks: | ||
+ | input flush_en, | ||
+ | |||
+ | == Control Logic Support == |
Revision as of 14:51, 27 March 2019
The following section describes all the basic components used in the design of the system. Such components are located in the src/common folder and due to their extensive use we dedicate this section to
Memory Banks
Two components are mainly used as memory banks:
- memory_bank_1r1w: 1 Read port and 1 Write port.
- memory_bank_2r1w: 2 Read ports and 1 Write port.
They both are memory elements (often mapped as a BRAM in Vivado), the first provides a simple interface and it is highly parametrizable in size, number of element of each line, number of bits for element:
parameter SIZE = 1024, parameter ADDR_WIDTH = $clog2( SIZE ), parameter COL_WIDTH = 8, parameter NB_COL = 4,
The reading interface is reported in the following snippet code, when the address is ready, and the enable is high, the SRAM produces on the output bus the requested data the next clock cycle.
input logic read_enable, input logic [ADDR_WIDTH - 1:0] read_address, output logic [NB_COL*COL_WIDTH - 1:0] read_data
Similarly, the writing interface is reported below. When the data to store and the address are ready, and the enable is set, the SRAM stores the incoming data in the selected address.
input logic [NB_COL - 1:0] write_enable, input logic [ADDR_WIDTH - 1:0] write_address, input logic [NB_COL*COL_WIDTH - 1:0] write_data,
The writing interface has a selective write_enable signal, this is a bitmap of which elements of the line are affected by the current operation. In case of concurrent write and read on the address, the behaviour of the SRAM depends on the mode selected on its parameters:
parameter WRITE_FIRST = "TRUE"
If "write_first" is enabled (true), the SRAM first stores the data in the memory then forwards the data just stored on the output signal. The other functionality mode is "read_first" (parameter WRITE_TRUE set to false), in this case, the module first fetch the old data from the memory and outputs it on the reading output signal, then stores into the memory the new data from the interface.
The second module (memory_bank_2r1w) provides a similar interface, although the memory_bank_2r1w has an extra reading port, obtained allocating two memory_bank_1r1w modules with their writing port connected together. In this way, each write operation is propagated to both elements, and the two memories are aligned in their content, thus the same reading operation performed on both fetches the same value.
FIFO
The sync_fifo module is extensively used in the design, it instantiates a parametrizable FIFO in term of width of the element and number of positions:
parameter WIDTH = 64, parameter SIZE = 4,
Two parameters are control-oriented and widely used in the architecture:
parameter ALMOST_FULL_THRESHOLD = SIZE, parameter ALMOST_EMPTY_THRESHOLD = 1
Those set when the FIFO should signal to the back-pressure logic when it is full or empty:
output logic full, output logic almost_full, output logic empty, output logic almost_empty,
In the default instantiation, the FIFO signals that it is full when the number of elements stored is equal to SIZE, ALMOST_FULL_THRESHOLD changes this rule, allowing the FIFO to signal the full condition in advance. The same for the empty condition.
Enqueuing an element in the FIFO can be easily done using the enqueue interface:
input enqueue_en, input [WIDTH - 1:0] value_i,
When at least one element is pending in the FIFO, it is propagated on the value_o signal output and the empty signal is low. The dequeue_en signal pops the element from the FIFO:
input dequeue_en, output [WIDTH - 1:0] value_o
Finally, the flush_en input signal empties the FIFO. Often used in case of rollbacks:
input flush_en,