O projeto utiliza o desenvolvedor AC703 da Xiaomei, implementando quatro contadores hierárquicos para gerenciar sgeundos, minutos, horas e dias. É necessário converter valores decimais para BCD para exibição e entre ASCII para comunicação serial. A protocolo de comunicação serial exige reconhecimento de caracteres específicos (":"), com formatação "HH:MM:SS".
Código do Módulo Principal
module clock_sistema(
clock_entrada,
reset_n,
rx_pronto,
dados_rx,
saida_display,
tx_serial
);
parameter TAMANHO_RX = 48;
parameter TAMANHO_TX = 72;
parameter TAMANHO_DISP = 32;
parameter DIVISOR_FREQ = 26;
parameter DIVISOR_CONTADOR = 50_000_000;
parameter SEGUNDOS_BITS = 6;
parameter MINUTOS_BITS = 6;
parameter HORAS_BITS = 5;
parameter BCD_BITS = 8;
parameter ASCII_BITS = 16;
parameter DECIMAL_BITS = 6;
input clock_entrada;
input reset_n;
input [TAMANHO_RX-1:0] dados_rx;
input rx_pronto;
output [TAMANHO_DISP-1:0] saida_display;
output tx_serial;
reg [TAMANHO_DISP-1:0] saida_display;
wire tx_serial;
reg [TAMANHO_TX-1:0] buffer_tx;
reg [DIVISOR_FREQ-1:0] contador_divisao;
wire sinal_contagem_divisao;
wire fim_contagem_divisao;
reg [SEGUNDOS_BITS-1:0] contador_segundos;
wire sinal_contagem_segundos;
wire fim_contagem_segundos;
reg [MINUTOS_BITS-1:0] contador_minutos;
wire sinal_contagem_minutos;
wire fim_contagem_minutos;
reg [HORAS_BITS-1:0] contador_horas;
wire sinal_contagem_horas;
wire fim_contagem_horas;
wire [BCD_BITS-1:0] bcd_segundos;
wire [BCD_BITS-1:0] bcd_minutos;
wire [BCD_BITS-1:0] bcd_horas;
wire [ASCII_BITS-1:0] ascii_segundos;
wire [ASCII_BITS-1:0] ascii_minutos;
wire [ASCII_BITS-1:0] ascii_horas;
wire [DECIMAL_BITS-1:0] decimal_segundos;
wire [DECIMAL_BITS-1:0] decimal_minutos;
wire [DECIMAL_BITS-1:0] decimal_horas;
reg sinal_configuracao;
always @(posedge clock_entrada or negedge reset_n) begin
if(!reset_n)
contador_divisao <= 0;
else if(sinal_contagem_divisao) begin
if(fim_contagem_divisao)
contador_divisao <= 0;
else
contador_divisao <= contador_divisao + 1;
end
end
assign sinal_contagem_divisao = 1;
assign fim_contagem_divisao = sinal_contagem_divisao && (contador_divisao == DIVISOR_CONTADOR - 1 || sinal_configuracao);
// Lógica de contagem para segundos
always @(posedge clock_entrada or negedge reset_n) begin
if(!reset_n) begin
contador_segundos <= 0;
end
else if(sinal_contagem_segundos) begin
if(fim_contagem_segundos)
contador_segundos <= 0;
else
contador_segundos <= contador_segundos + 1;
end
else if(sinal_configuracao)
contador_segundos <= decimal_segundos;
end
assign sinal_contagem_segundos = fim_contagem_divisao && !sinal_configuracao;
assign fim_contagem_segundos = sinal_contagem_segundos && (contador_segundos == 60 - 1);
// Lógica de contagem para minutos
always @(posedge clock_entrada or negedge reset_n) begin
if(!reset_n) begin
contador_minutos <= 0;
end
else if(sinal_contagem_minutos) begin
if(fim_contagem_minutos)
contador_minutos <= 0;
else
contador_minutos <= contador_minutos + 1;
end
else if(sinal_configuracao)
contador_minutos <= decimal_minutos;
end
assign sinal_contagem_minutos = fim_contagem_segundos && !sinal_configuracao;
assign fim_contagem_minutos = sinal_contagem_minutos && (contador_minutos == 60 - 1);
// Lógica de contagem para horas
always @(posedge clock_entrada or negedge reset_n) begin
if(!reset_n) begin
contador_horas <= 0;
end
else if(sinal_contagem_horas) begin
if(fim_contagem_horas)
contador_horas <= 0;
else
contador_horas <= contador_horas + 1;
end
else if(sinal_configuracao)
contador_horas <= decimal_horas;
end
assign sinal_contagem_horas = fim_contagem_minutos && !sinal_configuracao;
assign fim_contagem_horas = sinal_contagem_horas && (contador_horas == 24 - 1);
always @(posedge clock_entrada or negedge reset_n) begin
if(!reset_n)
saida_display <= 0;
else
saida_display <= {bcd_horas, 4'hF, bcd_minutos, 4'hF, bcd_segundos};
end
always @(posedge clock_entrada or negedge reset_n) begin
if(!reset_n)
buffer_tx <= 0;
else
buffer_tx <= {ascii_horas, 8'h3A, ascii_minutos, 8'h3A, ascii_segundos, 8'h0A};
end
always @(posedge clock_entrada or negedge reset_n) begin
if(!reset_n)
sinal_configuracao <= 0;
else if(rx_pronto)
sinal_configuracao <= 1;
else
sinal_configuracao <= 0;
end
uart_transmissor uart_transmissor_inst(
.clock(clock_entrada),
.reset_n(reset_n),
.dados(buffer_tx),
.ativar_transmissao(contador_divisao == 2 && sinal_contagem_divisao),
.saida_tx(tx_serial)
);
conversor_decimal_bcd conversor_segundos(
.clock(clock_entrada),
.reset_n(reset_n),
.valor_decimal(contador_segundos),
.saida_bcd(bcd_segundos)
);
conversor_decimal_bcd conversor_minutos(
.clock(clock_entrada),
.reset_n(reset_n),
.valor_decimal(contador_minutos),
.saida_bcd(bcd_minutos)
);
conversor_decimal_bcd conversor_horas(
.clock(clock_entrada),
.reset_n(reset_n),
.valor_decimal(contador_horas),
.saida_bcd(bcd_horas)
);
conversor_decimal_ascii conversor_ascii_segundos(
.clock(clock_entrada),
.reset_n(reset_n),
.valor_decimal(contador_segundos),
.saida_ascii(ascii_segundos)
);
conversor_decimal_ascii conversor_ascii_minutos(
.clock(clock_entrada),
.reset_n(reset_n),
.valor_decimal(contador_minutos),
.saida_ascii(ascii_minutos)
);
conversor_decimal_ascii conversor_ascii_horas(
.clock(clock_entrada),
.reset_n(reset_n),
.valor_decimal(contador_horas),
.saida_ascii(ascii_horas)
);
conversor_ascii_decimal conversor_decimal_segundos(
.clock(clock_entrada),
.reset_n(reset_n),
.entrada_ascii(dados_rx[15:0]),
.saida_decimal(decimal_segundos)
);
conversor_ascii_decimal conversor_decimal_minutos(
.clock(clock_entrada),
.reset_n(reset_n),
.entrada_ascii(dados_rx[31:16]),
.saida_decimal(decimal_minutos)
);
conversor_ascii_decimal conversor_decimal_horas(
.clock(clock_entrada),
.reset_n(reset_n),
.entrada_ascii(dados_rx[47:32]),
.saida_decimal(decimal_horas)
);
endmodule
Módulo Top-Level
module clock_top_level(
clock_entrada,
reset_n,
rx_serial,
saida_cp,
saida_st,
saida_ds,
tx_serial
);
input clock_entrada;
input reset_n;
input rx_serial;
output saida_cp;
output saida_st;
output saida_ds;
output tx_serial;
wire saida_cp;
wire saida_st;
wire saida_ds;
wire [31:0] dados_display;
wire enable_sinal;
wire [15:0] dados_saida;
wire [7:0] selecao;
wire [7:0] segmentos;
wire tx_serial;
wire [47:0] dados_relogio;
wire rx_pronto;
clock_sistema clock_inst(
.clock_entrada(clock_entrada),
.reset_n(reset_n),
.rx_pronto(rx_pronto),
.dados_rx(dados_relogio),
.saida_display(dados_display),
.tx_serial(tx_serial)
);
receptor_uart receptor_inst(
.reset_n(reset_n),
.clock(clock_entrada),
.rx_serial(rx_serial),
.rx_pronto(rx_pronto),
.dados_recebidos(dados_relogio)
);
driver_hc595 driver_inst(
.clock(clock_entrada),
.reset_n(reset_n),
.enable(enable_sinal),
.dados(dados_saida),
.cp_saida(saida_cp),
.st_saida(saida_st),
.ds_saida(saida_ds)
);
conversor_hex conversor_inst(
.clock(clock_entrada),
.reset_n(reset_n),
.dados_exibicao(dados_display),
.selecao(selecao),
.segmentos(segmentos),
.enable(enable_sinal)
);
assign dados_saida = {segmentos, selecao};
endmodule