module packet_link_m
(
input clk,
output wire clk1,
output wire clk2,
input rst_n,
input data_valid,
input [7:0] data_in,
output [7:0] data_len,
output frame_valid,
output [7:0] frame_out,
output [7:0] fifo_dout,
output wire rx,
output tx,
output fifo_empty,
input fifo_rd_en,
output packet_valid
);
reg rxd;
wire txmon,txd;
wire rmon,rst_sync;
wire clk_100MHz, clk_12_5MHz,clk_99_8MHz;
wire clk2;
clk_wiz_0 CLOCK
(
// Clock out ports
// .clk_out1(clk_640MHz),
// .clk_out2(clk_80MHz),
.clk_out1(clk_100MHz),
.clk_out2(clk_12_5MHz),
.clk_out3(clk_200MHz),
.clk_out4(clk_400MHz),
// Status and control signals
.reset(reset),
.locked(locked),
// Clock in ports
.clk_in1(clk)
);
assign clk1=clk_100MHz;
assign clk2=clk_12_5MHz;
assign refclk=clk_200MHz; // delay 45~135
uart_packet_tx Tx1 (
.clk(clk),
.clk1(clk1),
.clk2(clk2),
.rst_n(rst_n),
.data_valid(data_valid),
.data_in(data_in),
.data_len(data_len),
.frame_valid(frame_valid),
.frame_out(frame_out),
.tx(tx)
);
/*
TX Encoder
(
.refclk(refclk),
.rst(!rst_n),
.txd_in(tx),
.mon1(txmon),
.txd(txd)
);
*/
Decoder Dec
(
.clk(clk1),
.rst_n(rst_n),
.refclk(refclk),
.rx_in(tx),
.rx(rx)
);
wire clk1n=~clk1; // 수정해야함.
uart_packet_rx Rx1 (
// .clk(clk1),
.clk(clk1n),
.clk2(clk2),
.rst_n(rst_n),
.rx(rx), // 직렬 입력
.fifo_dout(fifo_dout), // FIFO 데이터 출력
.fifo_empty(fifo_empty), // FIFO 비어있음 플래그
.fifo_rd_en(fifo_rd_en), // 사용자 읽기 요청
.packet_valid(packet_valid) // 유효 패킷 수신 완료 플래그
);
/*
RX Decoder
(
.refclk(~refclk),
.rst(!rst_n),
.rxd_in(txd),
.mon1(rmon),
.rst_sync(rst_sync),
.rxd(rxd)
);
*/
endmodule
module packet_link_m
(
input clk,
output wire clk1,
output wire clk2,
input rst_n,
input data_valid,
input [7:0] data_in,
output [7:0] data_len,
output frame_valid,
output [7:0] frame_out,
output [7:0] fifo_dout,
output wire rx,
output tx,
output fifo_empty,
input fifo_rd_en,
output packet_valid
);
reg rxd;
wire txmon,txd;
wire rmon,rst_sync;
wire clk_100MHz, clk_12_5MHz,clk_99_8MHz;
wire clk2;
clk_wiz_0 CLOCK
(
// Clock out ports
.clk_out1(clk_100MHz),
.clk_out2(clk_12_5MHz),
.clk_out3(clk_200MHz),
.clk_out4(clk_400MHz),
// Status and control signals
.reset(reset),
.locked(locked),
// Clock in ports
.clk_in1(clk)
);
assign clk1=clk_100MHz;
assign clk2=clk_12_5MHz;
assign refclk=clk_200MHz; // delay 45~135
uart_packet_tx Tx1 (
.clk(clk),
.clk1(clk1),
.clk2(clk2),
.rst_n(rst_n),
.data_valid(data_valid),
.data_in(data_in),
.data_len(data_len),
.frame_valid(frame_valid),
.frame_out(frame_out),
.tx(tx)
);
/*
TX Encoder
(
.refclk(refclk),
.rst(!rst_n),
.txd_in(tx),
.mon1(txmon),
.txd(txd)
);
*/
Decoder Dec
(
.clk(clk1),
.rst_n(rst_n),
.refclk(refclk),
.rx_in(tx),
.rx(rx)
);
wire clk1n=~clk1; // 수정해야함.
uart_packet_rx Rx1 (
// .clk(clk1),
.clk(clk1n),
.clk2(clk2),
.rst_n(rst_n),
.rx(rx), // 직렬 입력
.fifo_dout(fifo_dout), // FIFO 데이터 출력
.fifo_empty(fifo_empty), // FIFO 비어있음 플래그
.fifo_rd_en(fifo_rd_en), // 사용자 읽기 요청
.packet_valid(packet_valid) // 유효 패킷 수신 완료 플래그
);
/*
RX Decoder
(
.refclk(~refclk),
.rst(!rst_n),
.rxd_in(txd),
.mon1(rmon),
.rst_sync(rst_sync),
.rxd(rxd)
);
*/
endmodule
module uart_packet_tx (
input wire clk,
input wire clk1,
input wire clk2,
input wire rst_n,
input wire data_valid,
input wire [7:0] data_in,
output reg [7:0] data_len, // 전체 데이터 길이
output reg frame_valid,
output reg [7:0] frame_out,
output reg tx
);
localparam IDLE = 3'd0,
SOF = 3'd1,
LEN = 3'd2,
DATA = 3'd3,
CRC = 3'd4,
EOF = 3'd5;
reg [2:0] state, next_state;
reg [7:0] data_cnt;
// reg [7:0] data_buf[255:0];
reg [7:0] data_buf[2047:0];
integer i;
reg data_valid_r;
always @(posedge clk1)
data_valid_r <= data_valid;
// 데이터 버퍼에 저장
always @(posedge clk1 or negedge rst_n) begin
if (!rst_n) begin
for (i = 0; i < 2048; i = i + 1)
data_buf[i] <= 8'd0;
data_cnt <= 12'd0;
end else if (data_valid && ~data_valid_r)
data_len<=data_in;
else if (data_valid && data_cnt < data_len) begin
data_buf[data_cnt] <= data_in;
data_cnt <= data_cnt + 1;
end
end
// 상태 전이
always @(posedge clk2 or negedge rst_n) begin
if (!rst_n) state <= IDLE;
else state <= next_state;
end
// 상태 결정
always @(*) begin
case (state)
IDLE: next_state = (data_cnt == data_len) ? SOF : IDLE;
SOF: next_state = LEN;
LEN: next_state = DATA;
DATA: next_state = (data_cnt == 0) ? CRC : DATA;
CRC: next_state = EOF;
EOF: next_state = IDLE;
default: next_state = IDLE;
endcase
end
// 출력 제어
reg [10:0] out_cnt;
reg [7:0] frame;
reg [7:0] crc_check;
reg [2:0] bcnt;
reg tx_n,tx_p;
always @(posedge clk1)
begin
if (!rst_n)
bcnt<=0;
else if(state==IDLE)
begin
bcnt<=0;
crc_check<=0;
end
else
bcnt<=bcnt+1'b1;
if(!rst_n)
tx_p<=1'b0;
else if(bcnt==3'b000)
begin
frame<=frame_out;
crc_check^=frame_out;
tx_p<=frame_out[7];
end
else
{tx_p,frame[6:1]}<=frame[7:0];
end
always @(*)
begin
if(clk1)
tx<=tx_n;
else
tx<=tx_p;
tx_n<=~tx_p;
end
always @(posedge clk2 or negedge rst_n) begin
if (!rst_n) begin
frame_valid <= 1'b0;
frame_out <= 8'd0;
out_cnt <= 8'd0;
end else begin
case (state)
SOF: begin
frame_valid <= 1'b1;
frame_out <= 8'h55;
end
LEN: begin
frame_valid <= 1'b1;
frame_out <= data_len;
out_cnt <= 1;
out_cnt <= 8'd0;
end
DATA: begin
if (out_cnt < data_len) begin
frame_valid <= 1'b1;
frame_out <= data_buf[out_cnt];
out_cnt <= out_cnt + 1;
end else begin
// frame_valid <= 1'b0;
frame_out <= crc_check;
frame_valid <=1'b1;
end
end
CRC: begin
frame_valid <= 1'b1;
//frame_out <= crc_check;
frame_out <= 8'hAA;
end
EOF: begin
frame_valid <= 1'b1;
frame_out <= 8'h00;
end
IDLE : begin
frame_valid <= 1'b0;
frame_out <= 8'd0;
end
default: begin
frame_valid <= 1'b0;
frame_out <= 8'd0;
end
endcase
end
end
endmodule
module uart_packet_rx (
input clk,
input clk2,
input rst_n,
input rx, // 직렬 입력
output [7:0] fifo_dout, // FIFO 데이터 출력
output fifo_empty, // FIFO 비어있음 플래그
input fifo_rd_en, // 사용자 읽기 요청
output packet_valid // 유효 패킷 수신 완료 플래그
);
// 상태정의
typedef enum logic [2:0] {
IDLE, SOF, LEN, DATA, EOF, ERR
} state_t;
state_t state, next_state;
reg [7:0] rx_data;
reg [7:0] len_cnt;
reg [7:0] data_cnt;
reg packet_valid_r;
// FIFO 인스턴스 (간단 예시)
wire fifo_wr_en;
wire fifo_full;
wire [7:0] fifo_din;
reg [7:0] rxData,rxData1;
reg [2:0] bCnt;
reg rxen;
reg FoundSync;
assign packet_valid = packet_valid_r;
always @(posedge clk)
begin
if(rst_n==1'b0)
rx_data<=0;
else
rx_data<={rx_data[6:0],rx};
if(rst_n==1'b0)
begin
bCnt<=0;
FoundSync<=1'b0;
end
else if(state==IDLE)
begin
if((rx_data==8'h55) &&(FoundSync==1'b0))
begin
bCnt<=0;
FoundSync<=1'b1;
end
else
begin
bCnt<=bCnt+1'b1;
FoundSync<=1'b0;
end
end
else
begin
bCnt<=bCnt+1'b1;
end
rxData1<=rx_data;
rxData<=rxData1;
if(bCnt==3'b0)
begin
rxen<=1'b1;
end
else
rxen<=1'b0;
end
// UART 수신부(별도 모듈로 분리 권장, 여기선 rx_data에 바이트 단위 입력 가정)
// ...
// 상태천이
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
state <= IDLE;
data_cnt <= 0;
len_cnt <= 0;
packet_valid_r <= 0;
end else if(rxen==1'b1)
begin
state <= next_state;
if(state == DATA && fifo_wr_en)
data_cnt <= data_cnt + 1;
else if(state == IDLE)
data_cnt <= 0;
if(next_state == LEN)
len_cnt <= rxData;
if(state == EOF)
packet_valid_r <= 1;
else
packet_valid_r <= 0;
end
end
// 상태 결정
always @(*) begin
next_state = state;
case(state)
IDLE: if(rxData == 8'h55) next_state = SOF;
SOF: next_state = LEN;
LEN: next_state = DATA;
DATA: if(data_cnt == len_cnt-1) next_state = EOF;
EOF: if(rxData == 8'hAA) next_state = IDLE;
else next_state = ERR;
ERR: next_state = IDLE;
endcase
end
// FIFO에 데이터 저장
assign fifo_wr_en = (next_state == DATA) && rxen==1'b1; // DATA상태에서만 기록
assign fifo_din = rxData;
// FIFO 인스턴스 (간단 예시)
simple_fifo u_fifo (
.clk(clk),
.rst_n(rst_n),
.din(fifo_din),
.wr_en(fifo_wr_en),
.rd_en(fifo_rd_en),
.dout(fifo_dout),
.empty(fifo_empty),
.full(fifo_full)
);
endmodule