Categorías
Verificación

Phases in UVM

UVM introduces the concept of phases to ensure that all objects are properly configured and connected before starting the runtime simulation. Phases contribute to a better synchronised simulation and enable to the verification engineer to get better modularity of the testbench.

UVM phases consists of:

  1. build
  2. connect
  3. end_of_elaboration
  4. start_of_simulation
  5. run
    1. reset
    2. configure
    3. main
    4. shutdown
  6. extract
  7. check
  8. report
  9. final

The run phase has been simplified to get a better picture of how phases worked. Nevertheless, all subphases in the run phase have a pre_ and post_ phase to add flexibility. Therefore, the run phase is actually composed by the following phases:

  1. run
    1. pre_reset
    2. reset
    3. post_reset
    4. pre_configure
    5. configure
    6. post_configure
    7. pre_main
    8. main
    9. post_main
    10. pre_shutdown
    11. shutdown
    12. post_shutdown

Although all phases play an important role, the most relevant phases are:

  • build_phase: objects are created
  • connect_phase: interconnection between objects are hooked
  • run_phase: the test starts. The run_phase is the only phase which is a task instead of a function, and therefore is the only one that can consume time in the simulation.

UVM phases are executed from a hierarchical point of view from top to down fashion. This means that the first object that executes a phase is the top object, usually

testbench  test  environment agent {monitor, driver, sequencer, etc}

Nevertheless, in the connect phase, this happens the other way round in a down to top fashion.

{monitor, driver, sequencer} agent environment test testbench

Categorías
Verificación

How to add UVM in your Verilog test bench

To use UVM in your Verilog test bench, you need to compile the UVM package top. To do so, you need to include it on your file by using:

`include "uvm_macros.svh"
`include "uvm_pkg.sv"
import uvm_pkg::*;

The uvm_pkg is contained in the uvm_pkg.sv that must be passed to the compiler. Therefore, it is necessary to indicate the UVM path to the compiler. In Cadence Incisive Enterprise Simulator (IES) is as easy as to specify -uvm switch.

In Modelsim, from Modelsim console, run:

vsim -work work +incdir+/path/to/uvm-1.1d/src +define+UVM_CMDLINE_NO_DPI +define+UVM_REGEX_NO_DPI +define+UVM_NO_DPI

After compilation, click on Simulate > Start simulation and select the tb in the work library. Then, run the simulation for the desired time.

Categorías
Diseño digital

Operation with different size operands in Verilog/SystemVerilog

When an operation such as an addtion or a substraction is done using different size operands than final variable, it is necessary to extend sign to ensure the operation is done properly.

Example:

logic signed [21:0] acc;
logic signed [5:0] data_in;
logic [3:0] offset;

Wrong:

acc = data_in + offset;

Sign on data_in will not be respected. data_in will be filled with 0 before doing the operation and won’t be taken as negative (if applies).

Correct:

acc = {{16{data_in[5]}},data_in} + offset;

Extend sign to match number of acc_add bits before doing operation

Categorías
Teoría de la señal

Onda estacionaria

Onda estacionaria creada por dos ondas viajeras.

Categorías
Teoría de la señal

Resolución FFT

\[ \Delta f = \frac{F_s}{N_{samples}} \]

Si por ejemplo, \(F_s = 5~GSa/s = 5\cdot10^9~Sa/s \) y \(N_{samples} = 25000\), la resolución frecuencial es de:

\[\Delta f = \frac{5 \cdot 10^9}{25000} = 200~kHz \]

Categorías
Sin categoría

Instalar minted en Windows 10

minted es un paquete de LaTeX que permite añadir código a tu documento y mostrarlo resaltado. Minted utiliza Python para compilar, por lo que el primer paso es instalar Python 2.6 o superior.

  1. Instalar Python
  2. Añadir la ruta de Python a las variables del entorno de Windows.
    1. Botón derecho en el icono de Windows.
    2. Sistema
    3. En el buscador añadir «variables» y clickar en «Editar variables del sistema».
    4. Clickar en Variables del entorno.
    5. En Variables del sistema, añadir a la entrada Path la localización de la carpeta Scripts de Python. En mi caso está en D:\Windows\Python\Python36-32\Scripts. Es muy probable que este paso no sea necesario en tu sistema y que al instalar Python ya se haya añadido la ruta a las variables del sistema. Si al ejecutar python en CMD da un error, entonces este paso es obligatorio.
    6. Instalar pip.
    7. Instalar pygments:
      1. Abrir CMD en Windows y escribir: pip install Pygments
      2. Probar que se ha instalado correctamente escribiendo en CMD pygmentize -h
    8. Ahora desde TexStudio hay que modificar la llamada al compilador de LaTeX.
      1. Opciones > Configurar TeXStudio > Órdenes
      2. Modificar las entradas LaTeX y PdfLaTeX por: latex.exe -src -interaction=nonstopmode -shell-escape %.tex y pdflatex.exe -synctex=1 -interaction=nonstopmode -shell-escape %.tex respectivamente. De esta manera se añade la etiqueta -shell-escape después de -interaction=nonstopmode
      3. Cerrar TeXStudio
      4. Abrir de nuevo

Y si no ha habido ningún problema en los pasos anteriores, se debería poder compilar utilizando minted. Para más información, visitad la guía de instalación de minted.

\begin{minted}[mathescape,
linenos,
numbersep=8pt,
gobble=0,
frame=lines,
framesep=2mm]{csharp}
    public static int width = 64;	// Landscape width
    public static int height = 128;	// Landscape height
    public static int depth = 64;	// Landscape depth
    public int heightScale = 20;	// Maximum terrain's height
    public float detailScale = 25.0f;
    public Transform vrCamera;
    public GameObject grassBlock;	// Grass block object
    Block[,,] worldBlocks = new Block[width, height, depth];// 3D array with blocks
\end{minted}

 

Categorías
Electrónica

Parameter sweep en Orcad Capture PSpice

  1. Instanciar PARAMETERS de la librería SPECIAL.
  2. Editar propiedades de PARAMETERSS (doble click).
  3. Click en «New property».
  4. Añadir parámetro. Ejemplo: Name: Vin_variable, Value: 0.7
  5. Modificar valor del componente asignando el nuevo parámetro entre {}. Ejemplo: VAMPL: {Vin_variable}
  6. Añadir «Parametric sweep» en la configuración del perfil de simulación.
  7. Por último, realizar la simulación.
Categorías
Electrónica

Memoria M9K en Cyclone IV

El dispositivo Cyclone IV de Altera dispone de unas memorias embebidas llamadas M9K. Estas memorias son configuradas por el sintetizador (Quartus) y dependiendo del tamaño necesario, se pueden combinar varias. Estas memorias siempre son síncronas, por lo que para que el sintenizador utilice una memoria M9K a partir del código, la memoria en cuestión debe estar gobernada por la señal de reloj.

Estas memorias pueden funcionar con un puerto puerto simple (entrada-salida) o un puerto doble. La configuración de puerto doble consiste en leer de manera independiente una misma memoria por dos puertos. Otra de los modos de funcionamiento es ROM, en el que se escribe el contenido al programar la FPGA y solo es posible leer su contenido.

Dependiendo de la configuración, la capacidad disponible las memorias M9K puede variar. Para anchos de palabra de 1, 2 y 4 bits la capacidad disponible es de 8k (8192 bits). Para tamaños de palabra mayores (8+1), (16+2), (32+4), la capacidad disponible es de 9k (9216 bits).

Las configuraciones en modo ROM son:

  • 8k x 1 bit
  • 4k x 2 bits
  • 2k x 4 bits
  • 1k x (8+1) bits
  • 512 x (16+2) bits
  • 256 x (32+4) bits

Las configuraciones en modo puerto doble son:

  • 8k x 1 bit
  • 4k x 2 bits
  • 2k x 4 bits
  • 1k x (8+1) bits
  • 512 x (16+2) bits

En el caso de los anchos de palabra no potencias de 2, se puede utilizar estos bits extras para control de errores.

Ejemplo de memoria 1k x 16

La primera opción está más optimizada ya que se necesita menos hardware para obtener el mismo resultado.

Categorías
Diseño digital

Circuitos aritméticos

Máxima frecuencia de trabajo

La frecuencia máxima de trabajo de un diseño digital, viene marcado por los tiempos de flip-flop, el tiempo de propagación en la lógica combinacional y el tiempo de setup. Para registar un dato a la salida de un flip-flop, es necesario un tiempo para pasar el nivel de entrada D1 a la salida Q1, lo que se conoce como tiempo de propagación de flip-flop. Luego, esta señal pasará a través de una lógica combinacional que añadirá un retardo. Este retardo en la figura anterior es \(t_{pLCR}\). Finalmente, para que último flip-flop pueda registrar el nivel de entrada, es necesario que este dato se mantenga al menos un tiempo de setup \(t_{su}\). Por tanto, el periodo mínimo de el ciclo de reloj debe ser:

\[ T_{p~min} = t_{pFF} + t_{pLCR} + t_{su} \]

Y la frecuencia máxima, será la inversa del periodo mínimo:

\[f_{max} = \frac{1}{T_{p~min}} \]

Los tiempo de setup y de flip-flop vienen determinados por la tecnología con la que se ha fabricado la FPGA. Por lo tanto, estos dos parámetros quedan invariables en un diseño. Para poder aumentar la frecuencia de trabajo, es necesario disminuir el tiempo de retardo que se produce en la lógica combinacional. Para ello, es necesario añadir registros en medio de la lógica combinacional que hagan que el retardo máximo entre flip-flops se minimice. Esto se conoce como pipelining.

Sin embargo, al añadir registros, el número de ciclos que tardará en salir el primer dato a la salida del sistema aumentará. El número de ciclos que tarda el primer dato en salir se conoce como latencia.

Para obtener el número negativo de un número en codificación Ca2, hay que negar todos los bit y sumar 1.

Cast de signed y unsigned

Para realizar la conversión números signed y unsigned en Verilog, existe la macro $signed() y $unsigned()

La macro $signed() extiende el bit de signo, de manera que si el valor de la variable unsigned tenía el MSB a 1, al hacer la conversión mediante la macro se obtendrá un valor negativo, machacando el valor original que tenía en formato unsigned.

A U[3,0] = 111 = 7
$signed(A) = -1

Sin embargo, si el número unsigned tenía el MSB a 0, el valor correspondiente después de la conversión será el mismo.

Cast a signed. Si el valor del MSB de uA está a 1, el valor de sA se modificará

Cuando se quiere pasar un número en formato signed a unsigned utilizando la macro $unsigned(), se hace una copia bit a bit del valor signed. Si son necesarios más bits porque la variable donde se copiará el valor posee más bits, se rellenará con ceros.

Aumentando el rango pero mateniendo el mismo tipo

Cuando se quiere aumentar el rango de una variable manteniendo el mismo formato de los números, Verilog sintetiza de manera diferente en función del formato original. En un formato signed, se hace una copia del bit de signo en todos los bits añadidos. En el caso de un formato unsigned, simplemente añade ceros.

Extensión de rango en formato signed
Extensión de rango en formato unsigned

Reduciendo el rango del número

Cuando se reduce el rango del número, se puede proceder de dos maneras. Una es con la técnica wrap, que consiste en no hacer nada. Los bits que ya no caben en el nuevo formato reducido, permanecen desconectados.

La otra manera, es utilizando el overflow. Con overflow, se consigue si al reducir el rango de un número, este supera el rango máximo representable, el valor definitivo queda como el máximo que se puede representar. Este técnica necesita de bloques adicionales para detectar si el número a reducir es mayor que el nuevo rango reducido y asignarle el máximo valor representable.

Bloques para detectar el overflow

Si el formato es con signo, la saturación puede ser positiva o negativa, por tanto hay que controlar ambos casos.

assign As = (A > SATpos) ? SATpos : (A<SATneg) ? SATneg : A[7:0];

Cambiando el ancho de palabra

Reduciendo la precisión con truncado

Para reducir la precisión de un formato, es decir, pasar de A[8,7] a B[5,4], por ejemplo, cuyo rango es [0,1] para ambos pero la precisión en A es de 0.0078125 y en B es de 0.0625, hay que coger los bits que correspondan.


En Verilog esto equivale a:

wire [7:0] A;
wire [4:0] B;

assign B = A[7:3];

Reduciendo la precisión con redondeo

Si hacemos la misma operación pero utilizando el redondeo, hay que tener en cuenta el bit anterior al menos significativo de los que estamos cogiendo para la nueva variable. De esta manera, si está 1, se redondeará hacia arriba y si está a 0 se redondeará hacia abajo.

wire [7:0] A;
wire [4:0] B;

assign B = A[7:3] + A[2];

Aumentando la precisión (o disminuyendo el escalado)

Cuando se añaden bits extras extremo de los LSB se aumenta la precisión del formato. Sin embargo, hay que posicionar correctamente los bits para que tengan el peso adecuado. A nivel de implementación consiste en conector todos los bits a la parte alta de la nueva variable.

En Verilog hay dos maneras de hacerlo. Asignar todos los bits de A a la parte alta de B y añadir 0 por abajo:

wire [4:0] A;
wire [7:0] B;

assign B = {A, 3'b0};

O asignando A a B desplazado 3 bits, ya que al mover rellenará con ceros.

wire [4:0] A;
wire [7:0] B;

assign B = A << 3;

Desplazamiento por una constante

Cuando se desplaza una variable por una constante, existen dos operadores para realizar el desplazamiento: >> y >>> (y sus equivalentes para la otra dirección de desplazamiento).

>> corresponde a un desplazamiento lógico, en el que no se tiene en cuenta si el MSB de la variable corresponden al bit de signo. Por tanto, al desplazar hacia la derecha pondrá ceros en la parte alta de la variable.

>>> corresponde a un desplazamiento aritmético, en el que sí se tiene en cuenta que el MSB es el bit de signo, de manera que al desplazar hacia la derecha hará una copia del signo. Por tanto, cada vez que se esté utilizando una variable signed, será necesario utilizar el desplazamiento aritmético (<<</>>>) para mantener el valor del signo.

Hay que tener en cuenta que si la variable destino a la que estamos asignando el desplazamiento tiene el mismo tamaño que la variable origen, se van a perder los bits que desplacemos. Por tanto, si queremos mantener esos bits que se desplazan la variable destino debe ser n bits mayor, donde n es el número de bits desplazados.

Las FPGAs como Altera Cyclone IV llevan incorporados arrays de bloques lógicos (LAB). Estos LABs en su interior están formados por Logic Elements (LE) que a su vez incorporan una LUT, un seguidor de acarreo y un registro.

Estos elementos son los componentes básicos para realizar operaciones de suma y multiplicación de una FPGA.

Suma

Suma manteniendo precisión

Al sumar manteniendo la precisión, es suficiente con alinear correctamente los bits y que la variable de destino tenga bits suficientes para alojar el resultado.

Suma recortando precisión

Al recortar la precisión, no hay que sumar todos los bits de los operandos. Solo hay que seleccionar los que se vayan a incorporar a la variable destino.

Resta

La resta (A-B) equivale a realizar un suma de A y con la inversión mediante Ca2 de B.  Para implementarla no es necesario añadir un sumador más y multiplexar la salida en función del signo. Simplemente hay que negar B y sumarlo con A.

 

Categorías
Sin categoría

Encontrar posición de un número dentro de una matriz en MATLAB

maxdB = max(meanFrequency);
maxPos = find(meanFrequency == maxdB);