El código descriptivo en Verilog es el siguiente:
reg [2:0] FFD=0; // 3 bits flips-flops tipo D.always @(posedge clk) FFD <= {FFD[1:0], cp}; // Registro de desplazamiento a izquierda.wire pulso= FFD[1] & !FFD[2]; // Esto es una AND con una de sus entradas negada.
reg load_r;always @(posedge clk) load_r <= load;
reg [31:0] shifter;always @(posedge clk) if (load_r) //-- Modo carga shifter <= d; else if (!load_r && pulso) //-- Modo desplazamiento shifter <= {1'b0, shifter[31:1]}; // Registro de desplazamiento a derecha.
assign qs = shifter[0]; // Salida por el bit menos significativo.
Esto es un registro de desplazamiento como en los chips estandar, es decir, que si el load está 1 hace la carga paralela, y cuando se pone a 0, cada vez que el CLK (el externo, no el reloj de 12MHz) recibe un pulso, se desplazan los bits.
Yo estoy utilizando mucho los registros de desplazamiento para comunicar la FPGA con un microcontrolador. Esta manera de trabajar es muy parecido a la comunicación SPI.
Y para terminar un ejemplo para leer los bits desplazado desde un Arduino, el código sería el siguiente:
Este código ya se publicó en otro post, sólo cambia la parte que hace la carga (variable 'ld'), aquí es de manera directa.
#define NOP __asm__ __volatile__ ("nop\n\t") // "No OPeration", para permitir un ciclo de reloj sin hacer nada; se utilizará como "nano-pausa" (un ciclo de reloj).
// Patillaje.const byte din = 5; // Número de pin de la entrada de datos series provenientes de la FPGA. (Registro de desplazamiento con la información de los pulsos del encoder óptico. 32 bits)const byte clk = 6; // Número de pin de la señal de pulso para el registro de desplazamiento en la FPGA. (idem)const byte ld = 7; // Número de pin de la señal para cargar el contador de pulsos al registro de desplazamiento en la FPGA. (idem)
// Variable general.int cnt = 0; // Contador general para el bucle For-Next.
// Acumulador de pulsos.long pulsos = 0; // Contador de pulsos.long aux = (2^32)-1; // Variables auxiliar para comparar si hay cambios. Cargamos al valor máximo para que imprima el valor desde el comienzo y no salga la pantalla vacía.
void setup(){ Serial.begin(115200); // Configuración del puerto serie virtual. pinMode(din, INPUT); // din como entrada. Estos son los tres pines para la lectura del registro de desplazamiento en la FPGA. (pin 5) pinMode(clk, OUTPUT); // clk como salida. (pin 6) pinMode(ld, OUTPUT); // ld como salida. (pin 7) digitalWrite(clk, LOW); // Esas dos salidas se inician con cero. digitalWrite(ld, LOW);}
void loop(){ digitalWrite(ld, HIGH); // Carga del registro de desplazamiento en la FPGA. NOP; // Un pequeño delay porque no se debe (en teoría) poner una instrucción seguida de otra en la que cambia el estado el mismo pin; en este caso es Load. digitalWrite(ld, LOW); // Hecho esto vuelve a cero. pulsos=0; // Ponemos a cero la variable pulsos; luego en el bucle "for" se irán poniendo a 1 los bits correspondientes. for (cnt = 0; cnt < 32; cnt++) // Lectura del registro de desplazamiento. { if (digitalRead(din)) bitSet(pulsos, cnt); // Inicialmente todos los bits de la variable "pulsos" están a cero. Aquí va poniendo a 1 los bits correspondientes. digitalWrite(clk, HIGH); // Flanco de subida de clk para pasar al siguiente bit del registro de desplazamiento de la FPGA. NOP; // Un pequeño delay porque no se debe (en teoría) poner una instrucción seguida de otra en la que cambia el estado el mismo pin; en este caso es clk. digitalWrite(clk, LOW); // Se pone a cero la señal clk para completar el pulso. }
if (aux != pulsos) // Si se produce algún cambio de contaje se muestra por el puerto serie. { Serial.println(pulsos); aux = pulsos; // Igualamos para luego ver si hay cambios. } }
Adjunto ejemplos aquí descritos.
Saludos!
reg [2:0] FFD=0; // 3 bits flips-flops tipo D.
always @(posedge clk) FFD <= {FFD[1:0], cp}; // Registro de desplazamiento a derecha.wire pulso=FFD[1] & !FFD[2];
reg load_r;always @(posedge clk) load_r <= load;
reg [7:0] shifter;
always @(posedge clk) if (load_r) //-- Modo carga shifter <= d; else if (!load_r && pulso) //-- Modo desplazamiento
shifter <= {1'b0, shifter[31:1]}; // Registro de desplazamiento a izquierda.
reg qs;always @(posedge clk) qs <= shifter[0]; // Salida serie registrada.
--
Has recibido este mensaje porque estás suscrito a un tema del grupo "FPGAwars: explorando el lado libre" de Grupos de Google.
Para cancelar la suscripción a este tema, visita https://groups.google.com/d/topic/fpga-wars-explorando-el-lado-libre/JhEzTXqtDuA/unsubscribe.
Para cancelar la suscripción a este grupo y a todos sus temas, envía un correo electrónico a fpga-wars-explorando-el...@googlegroups.com.
Para publicar en este grupo, envía un correo electrónico a fpga-wars-explora...@googlegroups.com.
Visita este grupo en https://groups.google.com/group/fpga-wars-explorando-el-lado-libre.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/fpga-wars-explorando-el-lado-libre/7b3fe5c4-7b4e-4fa6-a802-ffbca2ea2c76%40googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.