¡Problema de comunicación serie Verilog! Emergencia, ayuda! ¡Gracias! Solo quiero usar CPLD para implementar la comunicación en serie.
/*
La función de este módulo es verificar la función de comunicación serie básica con el PC. Es necesario instalar una herramienta de depuración del puerto serie en la PC para verificar el funcionamiento del programa.
El programa implementa un controlador de puerto serie que envía y recibe una trama de 10 bits (es decir, sin bit de paridad. Los 10 bits son 1 bit de inicio, 8 bits de datos y 1 bit de final).
La velocidad en baudios del puerto serie está determinada por el parámetro div_par definido en el programa. Al cambiar este parámetro se puede lograr la velocidad en baudios correspondiente. El valor de div_par establecido actualmente por el programa
es 0x104 y la velocidad en baudios correspondiente es 9600. Utilice un reloj de 8 veces la velocidad en baudios para dividir el tiempo del ciclo de envío o recepción de cada bit en 8 intervalos de tiempo para sincronizar la comunicación.
El trabajo básico del programa El proceso es presionar un botón SW0, el controlador envía "bienvenida" al puerto serie de la PC.
Después de recibirlo, la PC mostrará una pantalla para verificar si los datos son correctos (la herramienta de depuración del puerto serie está configurada para aceptar ASCII código).
La PC puede enviar datos hexadecimales 0-F a CPLD en cualquier momento, y CPLD los mostrará en el tubo digital de 7 segmentos después de recibirlos.
*/
módulo serial(clk, rst, rxd, txd, en, seg_data, key_input, lowbit);
entrada clk, primera;
entrada rxd; Fin de recepción de datos en serie
p>input key_input; //Entrada de clave
salida [7:0]en;
salida[7:0] seg_data;
reg [7:0] seg_data;
output txd; //Fin del envío de datos en serie
salida lowbit;
// /////// ////////////registro interno/////////////////////
reg [15:0] div_reg; // Contador divisor, el valor del divisor está determinado por la velocidad en baudios.
Después de la división de frecuencia, se obtiene un reloj con una frecuencia de 8 veces la velocidad en baudios
reg[2:0] div8_tras_reg; //El valor de conteo de este registro corresponde al número de intervalos de tiempo ubicados actualmente cuando enviando
reg[2:0] div8_rec_reg; //El valor de conteo de este registro corresponde al número de intervalo de tiempo actual al recibir
reg[3:0] state_tras; Transmitiendo registro de estado
reg[3:0] state_rec; //Aceptar registro de estado
reg clkbaud_tras //Enviar señal de habilitación a velocidad de baudios
reg; clkbaud_rec; //Con la señal de habilitación de recepción de la frecuencia en baudios
reg clkbaud8x; //Un reloj con una frecuencia de 8 veces la velocidad en baudios Su función es dividir el ciclo de reloj de envío o recepción. un poco en 8 intervalos de tiempo
reg recstart; //Comienza a enviar la bandera
reg recstart_tmp;
reg trasstart; //Comienza a recibir la bandera
reg rxd_reg1; //Recibir registro 1
reg rxd_reg2; //Recibir registro 2, debido a que los datos recibidos son una señal asíncrona, utiliza dos niveles de almacenamiento en búfer
reg txd_reg; //Transmitir registro
reg[7:0] rxd_buf; //Recibir caché de datos
reg[7:0] txd_buf //Enviar caché de datos
reg[2: 0] send_state; //Envía la cadena de "Bienvenida" a la PC cada vez que se presiona el botón. Este es el registro de estado de envío
reg[19:0] cnt_delay. ; //Retraso del contador de rebote
reg start_delaycnt; //Iniciar indicador de conteo de retraso
reg key_entry1, key_entry2 //Confirma que hay un indicador de pulsación de tecla
/////////// /////////////////////////////////////// /
parámetro div_par=16'h104; //Parámetro de división de frecuencia, su valor se calcula a partir de la velocidad en baudios correspondiente. La frecuencia del reloj dividida por este parámetro es 8 veces la velocidad en baudios. p> //El valor aquí corresponde a 9600 La velocidad en baudios, es decir, la frecuencia de reloj dividida es 9600*8
////////////////// ////////// //////////////////////
asignar txd=txd_reg;
assign lowbit=0;
assign en=8'b11111110; //asignación de señal de habilitación de tubo digital de 7 segmentos
always@(posedge clk)
comenzar
if(! rst) comenzar
cnt_delaylt;=0;
start_delaycntlt;=0
finalizar
;else if(start_delaycnt) comenzar p>
if(cnt_delay!=20'd800000) comenzar
cnt_delaylt;=cnt_delay 1;
finalizar
si no comenzar
cnt_delaylt;=0;
start_delaycntlt;=
0;
fin
fin
más comenzar
if(!key_inputamp;amp;cnt_delay==0)
start_delaycntlt;=1;
fin
fin
always@(posedge clk)
comenzar
if(!rst)
key_entry1lt;=0;
else comenzar
if(key_entry2)
key_entry1lt;=0 ;
else if(cnt_delay==20'd800000) comenzar
if(!key_input)
key_entry1lt;=1;
fin
fin
fin
siempre@(posedge clk )
comenzar
if(!rst)
div_reglt;=0;
else comenzar
if(div_reg==div_par-1)
div_reglt;=0;
else
div_reglt;=div_reg 1;
end
end
always@(posedge clk)/ /Dividimos la frecuencia para obtener un reloj con 8 veces la velocidad en baudios
begin
if(!rst)
clkbaud8xlt;=0;
else if(div_reg==div_par-1)
clkbaud8xlt;=~clkbaud8x;
end
always@(posedge clkbaud8x o negedge rst)
comenzar
if(!rst)
div8_rec_reglt;=0;
else if(recstart)//recibir bandera de inicio
div8_rec_reglt;=div8_rec_reg 1;//Después de que comienza la recepción, el número de intervalos de tiempo aumenta en 1 ciclo a un reloj de 8 veces la velocidad en baudios
end
siempre@(posedge clkbaud8x o negedge rst)
comenzar
if(!rst)
div8_tras_reglt;=0;
else if(trasstart) p>
div8_tras_reglt;=div8_tras_reg 1;//Después de que comienza la transmisión, el número de intervalos de tiempo aumenta en 1 ciclo bajo el reloj de 8 veces la velocidad en baudios
fin
siempre@( div8_rec_reg)
comenzar
if(div8_rec_reg==7)
clkbaud_rec=1; En la 7ª franja horaria la señal de habilitación de recepción es válida, Introducir datos
else
clkbaud_rec=0;
fin
siempre @(di
v8_tras_reg)
begin
if(div8_tras_reg==7)
clkbaud_tras=1; //En el séptimo intervalo de tiempo, la señal de habilitación de transmisión es válida, Enviar datos
else
clkbaud_tras=0;
end
always@(posedge clkbaud8x o negedge rst)
comenzar
if(!rst) comenzar
txd_reglt;=1;
trasstartlt;=0;
txd_buflt; 0;
state_traslt; =0;
enviar_statelt;
key_entry2lt;
else comenzar
if(!key_entry2) comenzar
if(key_entry1) comenzar
key_entry2lt;=1;
txd_buflt ;=8'd119; //"w"
fin
fin
else comienza
caso(state_tras) p >
4'b0000: comenzar //Enviar bit de inicio
if(!trasstart&send_statelt;7)
trasstartlt;=1;
else if(send_statelt; 7) comenzar
if(clkbaud_tras) comenzar
txd_reglt;=0;
state_traslt;=state_tras 1;
p>fin
fin
más comenzar
key_entry2lt;=0;
state_traslt;=0;
fin
fin
4'b0001: comenzar //Enviar el primer bit
if(clkbaud_tras) comenzar
txd_reglt;=txd_buf[0];
txd_buf[6:0]lt;=txd_buf[7:1];
state_traslt;=state_tras 1;
fin
fin
4'b0010: comenzar //Enviar el 2º bit
if(clkbaud_tras) comenzar
txd_reglt;= txd_buf[0];
txd_buf[6:0]lt;=txd_buf[7:1];
state_traslt;=state_tras 1;<
/p>
end
end
4'b0011: comenzar //Enviar el 3er bit
if(clkbaud_tras) comenzar
txd_reglt;=txd_buf[0];
txd_buf[6:0]lt;=txd_buf[7:1];
state_traslt;=state_tras 1;
end
end
4'b0100: comenzar //Enviar el 4º bit
if(clkbaud_tras) comenzar
txd_reglt ;=txd_buf[0];
txd_buf[6:0]lt;=txd_buf[7:1];
state_traslt;=state_tras 1;
end
end
4'b0101: comenzar //Enviar el 5º bit
if(clkbaud_tras) comenzar
txd_reglt;=txd_buf [0];
txd_buf[6:0]lt; =txd_buf[7:1];
state_traslt; =state_tras 1; p> p>
end
4'b0110: comenzar //Enviar el 6º bit
if(clkbaud_tras) comenzar
txd_reglt;=txd_buf[ 0] ;
txd_buf[6:0]lt;=txd_buf[7:1];
state_traslt;=state_tras 1;
fin
end
4'b0111: comenzar //Enviar el 7mo bit
if(clkbaud_tras) comenzar
txd_reglt;=txd_buf[0];
p>txd_buf[6:0]lt;=txd_buf[7:1];
state_traslt;=state_tras 1;
fin
end
4'b1000: comenzar //Enviar el 8.º bit
if(clkbaud_tras) comenzar
txd_reglt;=txd_buf[0];
txd_buf[6:0]lt;=txd_buf[7:1];
state_traslt;=state_tras 1;
fin
end
4'b1001: comenzar //Enviar bit de parada
if(clkbaud_tras) comenzar
txd_reglt;=1;
txd_buflt;=8'h55;
state_traslt;=state_tras 1;
fin
fin p> p>
4'b1111: comenzar
if(clkbaud_tras) comenzar
state_traslt;=state_tras 1;
send_statelt;=send_state 1;
p>
trasstartlt;=0;
case(send_state)
3'b000:
txd_buflt;=8 'd101; //"e "
3'b001:
txd_buflt;=8'd108;//"l"
3'b010:
txd_buflt ;=8'd99;//"c"
3'b011:
txd_buflt;=8'd111;//"o" p>
3'b100:
txd_buflt;=8'd109;//"m"
3'b101:
txd_buflt;=8 'd101;//"e "
predeterminado:
txd_buflt;=0;
endcase
end
fin
predeterminado: comenzar
if(clkbaud_tras) comenzar
state_traslt;=state_tras 1;
trasstartlt;=1;
fin
fin
fin
fin
fin
fin
fin
fin
fin
fin
fin
fin p>
always@ (posedge clkbaud8x o negedge rst)//Aceptar datos de la PC
comenzar
if(!rst) comenzar
rxd_reg1lt; =0;
rxd_reg2lt;=0;
rxd_buflt;=0;
state_reclt;=0;
recstartlt;=0 ;
recstart_tmplt;=0;
fin
si no comienza
rxd_reg1lt;=rxd;
rxd_reg2lt ;=rxd_reg1;
p>if(state_rec==0) comenzar
if(recstart_tmp==1) comenzar
recstartlt;=1; p>
> recstart_tmplt;=0;
state_reclt;=state_rec 1;
end
else if(!rxd_reg1amp;rxd_reg2) //Inicio detectado El flanco descendente de bit, ingresa al estado de aceptación
recstart_tmplt;=1;
end
else if(state_recgt;=1amp;amp;state_reclt;=8) start
if(clkbaud_rec) comenzar
rxd_buf[7]lt;=rxd_reg2;
rxd_buf[6:0]lt;=rxd_buf[7:1 ];
state_reclt; = state_rec 1;
fin
fin
else if(state_rec==9) comenzar
if(clkbaud_rec) comenzar
state_reclt;=0;
recstartlt;=0;
fin
fin
end
end
always@(rxd_buf) //Muestra los datos recibidos con un tubo digital
begin
caso (rxd_buf)
8'h30:
seg_data=8'b0000_0011
8'h31:
seg_data =8' b1001_1111;
8'h32:
seg_data=8'b0010_0101;
8'h33:
seg_data=8' b0000_1101;
8'h34:
seg_data=8'b1001_1001;
8'h35:
seg_data=8'b0100_1001 ; p>
8'h36:
seg_data=8'b0100_0001;
8'h37:
seg_data=8'b0001_1111;
8'h38:
seg_data=8'b0000_0001;
8'h39:
seg_data=8'b0001_1001; > 8'h41:
seg_data=8'b0001_0001;
8'h42:
seg_data=8'b1100_0001;
8 'h43:
seg_data=8'b0110_0011
8'h44:
seg_data=8'b1000_0101
8'h45; :
seg_data=8'b0110_0001
8'h46:
seg_data=8'b0111_0001;
valor predeterminado:
seg_data=8'b1111_1111
caso final
fin
endmodule