Académique Documents
Professionnel Documents
Culture Documents
Open source
Business
Explore
Pricing
Blog
Support
This repository
Obijuan / open-fpga-verilog-tutorial
Code
Issues 0
Pull requests 0
Search
Watch
Wiki
Pulse
Sign in
13
Star
31
Sign up
Fork
15
Graphs
Pages 40
Inicio (EN)
Captulos
Introduccin
Disearemos una unidad de recepcin serie asncrona, que nos permita recibir datos tanto del
PC como de otro dispositivo de comunicacin serie. Obtendremos el componente final, listo para
usar en nuestros diseos
Para probarla haremos dos ejemplos: uno que saca los 4 bits menos segnificativos del dato
recibido por los leds de la ICEStick. Y otro que hace eco de todos los caracteres recibidos. Los
caracteres recibidos se envan al transmisor serie para que lleguen de nuevo al PC. Esto nos
permitir comprobar que efectivamente hemos recibido el dato correctamente.
Mdulo UART-RX
La unidad de transmisin serie la encapsularemos dentro del mdulo uart-rx
https://github.com/Obijuan/open-fpga-ve
Descripcin de la interfaz
Clone in Desktop
converted by Web2PDFConvert.com
Entradas:
clk: Reloj del sistema (12MHz en la ICEstick)
rstn: Reset negado. Cuando rstn es 0, se hace un reset sncrono de la unidad de
transmisin
rx: Linea de recepcin serie. Por donde llegan los datos en serie
Salidas:
rcv: Notificacin de carcter recibido. Es un pulso de 1 ciclo de ancho
data: Dato de recibido (8 bits)
Cronograma
Inicialmente, cuando la lnea est en reposo y no se ha recibido nada, la seal rcv est a 0. Al
recibirse el bit de start por rx, el receptor comienza a funcionar, leyendo los siguientes bits y
almacenndolos internamente en su registro de desplazamiento. En el instante t1, cuando se ha
recibido el bit de stop, el dato se captura y se saca por la salida data. En el siguiente ciclo de
reloj, instante t2 (en el cronograma el tiempo se ha exagerado para que se aprecie), aparece un
pulso de un ciclo de reloj de anchura (exagerado tambin en el dibujo) que permita capturar el dato
en un registro externo.
Esta interfaz es muy cmoda. Para usar uart-rx en nuestros diseos, slo hay que conectar la
salida data a la entrada de datos de un registro y la seal rcv usarla como habilitacin. El dato
recibido se capturar automticamente. Esta seal rcv tambin la podemos usar en los
controladores para saber cundo se ha recibido un dato nuevo.
Diagrama de bloques
El diagrama de bloques completo del receptor se muestra en la siguiente figura:
converted by Web2PDFConvert.com
Ruta de datos
La seal rx se registra, para cumplir con las normas de diseo sncrono, y se introduce por el bit
ms significativo de un registro de desplazamiento de 10 bits. El desplazamiento se realiza
cuando llega un pulso por la seal clk_baud, proveniente del generador de baudios. Este
generador slo funciona cuando la miroorden bauden est activada.
Un contador de 4 bits realiza la cuenta de los bits recibidos (cuenta cada pulso de clk_baud). Se
pone a 0 con la microrden clear
Por ltimo tenemos el controlador, que genera las micrordenes baudgen, load, clear y la seal
de interfaz rcv. La seal load se activa para que el dato recibido se almacene en el registro de
datos de 8 bits, de manera que se mantenga estable durante la recepcin del siguiente carcter
En el cronograma se puede ver cmo al recebir el flanco de bajada del bit de start bauden se
activa, para que comience a funcionar el reloj del receptor. Sin embargo, hasta que no ha
alcanzado la mitad del periodo de bit no se pone a 1. A partir de entonces, los pulsos coinciden
con la mitad de los periodos de los bits recibidos
converted by Web2PDFConvert.com
Controlador
El controlador est modelado como una mquina de 4 estados:
IDLE: Estado de reposo. Esperando a recibir el bit de start por rx. En cuanto se recibe se pasa
al siguiente estado
RCV: Recibiendo datos. Se activa el temporizador de bits mediante la microorden baudgen y
se van recibiendo todos los bits, que se almacenan en el registro de desplazamiento. Cuando
se han recibido 10 bits (1 de start + 8 de datos + 1 de stop) la salida del contador (bitc) estar
a 10 y se pasa al siguiente estado
LOAD: Almacenamiento del dato recibido. Se activa la microorden load para guardar el dato
recibido (8 bits) en el registro de datos
DAV: (Data AVailable). Sealizacin de que existe un dato disponible. Se pone a uno la seal
rcv para que los circuitos externos puedan capturar el dato
Descripcin en verilog
La unidad de recepcin se compone de dos ficheros: el generador de baudios de recepcin
(baudgen_rx.v) y el propio receptor (uart_rx.v)
baudgen_rx.v
Este componente es similar al generador de baudios del transmisor, pero una vez habilitado el pulso
se enva transcurrida la mitad del periodo
El cdigo verilog es el siguiente:
converted by Web2PDFConvert.com
uart_rx.v
Descripcin en verilog de la unidad de recepcin:
//-- Fichero: uart_rx.v
`default_nettype none
`include "baudgen.vh"
module uart_rx (input wire
input wire
input wire
output reg
output reg
clk,
rstn,
rx,
rcv,
[7:0] data);
//-//-//-//-//--
//------------------------------------------------------------------//-RUTA DE DATOS
//------------------------------------------------------------------//-- Registrar la seal de recepcion de datos
//-- Para cumplir con las normas de diseo sincrono
always @(posedge clk)
rx_r <= rx;
//-- Divisor para la generacion del reloj de llegada de datos
baudgen_rx #(BAUD)
baudgen0 (
.clk(clk),
.clk_ena(bauden),
.clk_out(clk_baud)
);
//-- Contador de bits
reg [3:0] bitc;
always @(posedge clk)
if (clear)
bitc <= 4'd0;
else if (clear == 0 && clk_baud == 1)
bitc <= bitc + 1;
IDLE :
//-- Al llegar el bit de start se pasa al estado siguiente
if (rx_r == 0)
state <= RECV;
else
state <= IDLE;
//--- Recibiendo datos
RECV:
//-- Vamos por el ultimo bit: pasar al siguiente estado
if (bitc == 4'd10)
state <= LOAD;
else
state <= RECV;
//-- Almacenamiento del dato
LOAD:
state <= DAV;
//-- Sealizar dato disponible
DAV:
state <= IDLE;
default:
state <= IDLE;
endcase
endmodule
rxleds.v: Descripcin
El Diagrama de bloques del circuito se muestra a continuacin:
converted by Web2PDFConvert.com
converted by Web2PDFConvert.com
`default_nettype none
`include "baudgen.vh"
//-- Top design
module rxleds(input wire clk,
input wire rx,
output reg [3:0] leds,
output wire act);
//-//-//-//--
Simulacin
El banco de pruebas genera el reloj del sistema y enva dos caracteres en serie. Para facilitar el
envo y poder realizar bancos de pruebas ms elaborados, que puedan enviar mayor cantidad de
datos, se ha creado la tarea send_car. En Verilog, las tareas son como las funciones en C (pero sin
devolver ningn valor). Permiten reutilizar el cdigo y hacer que los bancos de prueba sean ms
sencillos y legibles
El cdigo de send_car es:
converted by Web2PDFConvert.com
task send_car;
input [7:0]
begin
rx <= 0;
#BITRATE rx
#BITRATE rx
#BITRATE rx
#BITRATE rx
#BITRATE rx
#BITRATE rx
#BITRATE rx
#BITRATE rx
#BITRATE rx
#BITRATE rx
end
endtask
car;
<=
<=
<=
<=
<=
<=
<=
<=
<=
<=
car[0];
car[1];
car[2];
car[3];
car[4];
car[5];
car[6];
car[7];
1;
1;
//-//-//-//-//-//-//-//-//-//-//--
Bit start
Bit 0
Bit 1
Bit 2
Bit 3
Bit 4
Bit 5
Bit 6
Bit 7
Bit stop
Esperar a que se envie bit de stop
Recibe como argumento un carcter de 8 bits y saca por la seal rx la trama serie, comenzando
por el bit de start, luego los de datos y finalmente el bit de stop. Se hace a la velocidad indicada por
el parametro BITRATE que se define en funcin de la velocidad en baudios.
Para enviar un caracter slo hay que invocar a la tarea y pasar este caracter como parmetro. Por
ejemplo, para enviar una "A" en ascii slo habra que ejecutar:
senc_car("A");
El cdigo completo del banco de pruebas es el siguiente:
//-- Fichero rxleds_tb.v
`include "baudgen.vh"
module rxleds_tb();
localparam BAUD = `B115200;
//-- Tics de reloj para envio de datos a esa velocidad
//-- Se multiplica por 2 porque el periodo del reloj es de 2 unidades
localparam BITRATE = (BAUD << 1);
//-- Tics necesarios para enviar una trama serie completa, mas un bit adicional
localparam FRAME = (BITRATE * 10);
//-- Tiempo entre dos bits enviados
localparam FRAME_WAIT = (BITRATE * 4);
//---------------------------------------//-- Tarea para enviar caracteres serie
//---------------------------------------task send_car;
input [7:0] car;
begin
rx <= 0;
//-- Bit start
#BITRATE rx <= car[0]; //-- Bit 0
#BITRATE rx <= car[1]; //-- Bit 1
#BITRATE rx <= car[2]; //-- Bit 2
#BITRATE rx <= car[3]; //-- Bit 3
#BITRATE rx <= car[4]; //-- Bit 4
#BITRATE rx <= car[5]; //-- Bit 5
#BITRATE rx <= car[6]; //-- Bit 6
#BITRATE rx <= car[7]; //-- Bit 7
#BITRATE rx <= 1;
//-- Bit stop
#BITRATE rx <= 1;
//-- Esperar a que se envie bit de stop
end
endtask
//-- Registro para generar la seal de reloj
reg clk = 0;
converted by Web2PDFConvert.com
Se envan dos caracteres de prueba. Primero el 0x55, que en binario es 01010101 (se alternan los
ceros y los unos). El segundo es el carcter K
Para realizar la simulacin ejecutamos el comando:
$ make sim
converted by Web2PDFConvert.com
Sntesis y pruebas
Hacemos la sntesis con el siguiente comando:
$ make sint
Recurso
ocupacin
PIOs
7 / 96
PLBs
18 / 160
BRAMs
0 / 16
converted by Web2PDFConvert.com
Ejemplo 2: eco
Este segundo ejemplo es el clsico programa de "eco": que transmite todo lo que recibe. Es una
manera de comprobar que los caracteres se estn recibiendo correctamente
Descripcin
El diagrama de bloques se muestra a continuacin:
Slo se instancian la unidad de transmisin y recepcin, y se conectan de manera que lo recibido por
una llegue a la otra
El cdigo verilog es el siguiente:
converted by Web2PDFConvert.com
`default_nettype none
`include "baudgen.vh"
//-- Top design
module echo(input wire clk,
input wire rx,
output wire tx
);
de transmision
//-//-//-//-//-//--
endmodule
Simulacin
El banco de pruebas es similar al del ejemplo anterior: enva dos caracteres
`include "baudgen.vh"
module echo_tb();
localparam BAUD = `B115200;
//-- Tics de reloj para envio de datos a esa velocidad
//-- Se multiplica por 2 porque el periodo del reloj es de 2 unidades
localparam BITRATE = (BAUD << 1);
//-- Tics necesarios para enviar una trama serie completa, mas un bit adicional
localparam FRAME = (BITRATE * 10);
converted by Web2PDFConvert.com
converted by Web2PDFConvert.com
Sntesis y pruebas
Hacemos la sntesis con el siguiente comando:
$ make sint2
Recurso
ocupacin
PIOs
10 / 96
PLBs
44 / 160
BRAMs
0 / 16
Ejercicios propuestos
TODO
Conclusiones
converted by Web2PDFConvert.com
TODO
converted by Web2PDFConvert.com