ADC데이터를 받아 UART 전송하기 위한 모듈입니다.
`timescale 1ns / 1ps // 시뮬레이션 스케일 설정
//이 모듈은 ADC 데이터와 채널 정보를 UART 전송 가능한 ASCII 문자로 변환하는 역할을 합니다.
//uart_ad는 UART를 통해 전송할 ASCII 문자를 저장하는 배열입니다.
//모듈은 UART 전송 프로세스를 제어하기 위한 상태 머신(uart_stat 및 uart_cnt)을 사용합니다.
//각 채널에 대한 ASCII 문자는 uart_ad에 저장되며, 모듈은 UART 인터페이스를 통해 이 문자들을 하나씩 전송합니다.
//모듈에는 UART 전송을 제어하기 위한 일정한 대기 기간이 있습니다.
module uart(
input clk50, // 50MHz 클럭 입력
input reset_n, // 리셋 신호, active-low
input [17:0] ch1_dec,
input [17:0] ch2_dec,
input [17:0] ch3_dec,
input [17:0] ch4_dec,
input [17:0] ch5_dec,
input [17:0] ch6_dec,
input [17:0] ch7_dec,
input [17:0] ch8_dec,
input [7:0] ch1_sig,
input [7:0] ch2_sig,
input [7:0] ch3_sig,
input [7:0] ch4_sig,
input [7:0] ch5_sig,
input [7:0] ch6_sig,
input [7:0] ch7_sig,
input [7:0] ch8_sig,
output tx // UART 전송 출력
);
/********************************************/
// 상수 및 문자열 정의
/********************************************/
reg [7:0] uart_ad [113:0]; // ASCII 문자를 저장하는 배열
/********************************************/
// UART 전송을 위한 상태 머신
/********************************************/
reg [15:0] uart_cnt; // UART 전송을 제어하기 위한 카운터
reg [2:0] uart_stat; // UART 전송 상태
reg [7:0] txdata; // 전송할 데이터
reg wrsig; // UART 전송 신호
reg [8:0] k; // 인덱스 카운터
reg [15:0] Time_wait; // 대기 시간을 설정하는 카운터
always @(clk)
begin
// 상태가 000일 때 ASCII 문자 설정
if(uart_stat==3'b000) begin
uart_ad[0]<=65; // 'A'
uart_ad[1]<=68; // 'D'
// ... (각 채널 및 문자 설정)
uart_ad[113]<=13; // 캐리지 리턴 (CR)
end
// ... (다른 상태에 대한 설정)
end
always @(posedge clk)
begin
// 리셋 시 초기화
if(!reset_n) begin
uart_cnt <= 0;
uart_stat <= 3'b000;
k <= 0;
end
else begin
// 상태 머신
case(uart_stat)
// 상태 000: 대기 상태
3'b000: begin
// 대기 시간이 16비트 최댓값에 도달하면 상태 변경
if (Time_wait == 16'hffff) begin
uart_stat <= 3'b001;
Time_wait <= 0;
end
else begin
uart_stat <= 3'b000;
Time_wait <= Time_wait + 1'b1;
end
end
// ... (다른 상태에 대한 설정)
endcase
end
end
/********** 클럭 분주 모듈 ***********/
clkdiv u0 (
.clk50 (clk50),
.clkout (clk)
);
/************* UART 전송 모듈 ************/
uarttx u1 (
.clk (clk),
.datain (txdata),
.wrsig (wrsig),
.idle (idle),
.tx (tx)
);
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Module Name: clkdiv
//50MHz의 입력 클럭(clk50)을 받아서 분주된 클럭(clkout)을 만드는 Verilog 모듈입니다.
//50MHz의 클럭을 이용하여 162 사이클 동안 클럭을 높은 상태로 유지한 후,
//그 다음 163 사이클 동안 클럭을 낮은 상태로 유지하여 출력 클럭을 생성합니다.
//이러한 동작을 반복하면서 50MHz 클럭을 분주하여 새로운 클럭을 만듭니다.
//////////////////////////////////////////////////////////////////////////////////
module clkdiv(clk50, clkout);
input clk50; // 50MHz 클럭 입력
output clkout; // 분주된 클럭 출력
reg clkout; // 출력된 클럭 레지스터
reg [15:0] cnt; // 16비트 카운터
always @(posedge clk50) // 50MHz 클럭의 상승 에지에서 동작
begin
if(cnt == 16'd162) // 카운터 값이 162인 경우
begin
clkout <= 1'b1; // 출력 클럭을 높은 상태로 설정
cnt <= cnt + 16'd1; // 카운터를 1 증가
end
else if(cnt == 16'd325) // 카운터 값이 325인 경우
begin
clkout <= 1'b0; // 출력 클럭을 낮은 상태로 설정
cnt <= 16'd0; // 카운터를 초기화
end
else
begin
cnt <= cnt + 16'd1; // 그 외의 경우에는 카운터를 1 증가
end
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Module Name: uarttx
//UART 통신에서 데이터를 전송하는 모듈을 구현한 Verilog 코드입니다.
//cnt라는 8비트 카운터를 사용하여 데이터 비트와 스톱 비트를 제어하며,
//paritymode에 따라 패리티 비트를 계산합니다.
//////////////////////////////////////////////////////////////////////////////////
module uarttx(clk, datain, wrsig, idle, tx);
input clk; // UART 클럭 입력
input [7:0] datain; // 전송할 8비트 데이터 입력
input wrsig; // 전송 신호 (1 사이클 동안 유효)
output idle; // 전송이 끝났을 때 high, 전송 중일 때 low
output tx; // UART 전송 데이터 출력
reg idle, tx; // 전송 상태 및 출력 데이터 레지스터
reg send; // 전송 중인지 여부를 나타내는 레지스터
reg wrsigbuf, wrsigrise; // wrsig 신호와 그 변화 여부를 나타내는 레지스터
reg presult; // 패리티 비트 계산 결과를 나타내는 레지스터
reg[7:0] cnt; // 8비트 전송을 위한 카운터
parameter paritymode = 1'b0; // 패리티 모드 (0: 짝수 패리티, 1: 홀수 패리티)
// wrsig 신호와 그 변화 여부를 나타내는 레지스터 업데이트
always @(posedge clk)
begin
wrsigbuf <= wrsig;
wrsigrise <= (~wrsigbuf) & wrsig;
end
// 전송 동작을 수행하는 블록
always @(posedge clk)
begin
if (wrsigrise && (~idle)) // wrsig가 상승 에지에서 변하고 현재 전송이 끝나지 않았을 때
begin
send <= 1'b1; // 전송 시작
end
else if(cnt == 8'd168) // 8비트 전송이 끝나면
begin
send <= 1'b0; // 전송 종료
end
end
// 전송 동작을 수행하는 블록
always @(posedge clk)
begin
if(send == 1'b1) begin
case(cnt) // 카운터 값에 따라 동작 수행
8'd0: begin
tx <= 1'b0;
idle <= 1'b1;
cnt <= cnt + 8'd1;
end
8'd16, 8'd32, 8'd48, 8'd64, 8'd80, 8'd96, 8'd112, 8'd128: begin
tx <= datain[cnt/16]; // 데이터 비트 설정
presult <= datain[cnt/16] ^ presult; // 패리티 비트 계산
idle <= 1'b1;
cnt <= cnt + 8'd1;
end
8'd144: begin
tx <= presult; // 패리티 비트 설정
presult <= datain[0] ^ paritymode; // 다음 패리티 비트 계산을 위한 초기화
idle <= 1'b1;
cnt <= cnt + 8'd1;
end
8'd160: begin
tx <= 1'b1; // 스톱 비트 설정
idle <= 1'b1;
cnt <= cnt + 8'd1;
end
8'd168: begin
tx <= 1'b1; // 스톱 비트 설정
idle <= 1'b0; // 전송 종료 상태 설정
cnt <= cnt + 8'd1;
end
default: begin
cnt <= cnt + 8'd1;
end
endcase
end
else begin
tx <= 1'b1;
cnt <= 8'd0;
idle <= 1'b0;
end
end
endmodule
'VERILOG' 카테고리의 다른 글
Hook script file 에러 시 해결 방법 (0) | 2024.02.27 |
---|---|
ZCU102-G + AD7606C18 Simultaneous Sampling ADC 8ch 18Bit -4 parallel (1) | 2024.02.27 |
ZCU102-G + AD7606C18 Simultaneous Sampling ADC 8ch 18Bit -2 parallel (1) | 2024.02.27 |
ZCU102-G + AD7606C18 Simultaneous Sampling ADC 8ch 18Bit -1 parallel (1) | 2024.02.27 |
Check the status of your licenses in the Vivado License Manager error (1) | 2024.02.27 |