绘制模块框图及状态图

彩色模块是ip核,灰色模块的b_code和uart_tx直接调用之前的模块代码即可。



编写模块代码
uart_send_IRIG_data_top
module uart_send_IRIG_data_top(
input wire clk ,
input wire rst_n ,
output wire tx
);
wire clk_125Mhz ;
wire locked ;
wire ex_b_code ;
wire [3:0] miao_gewei ;
wire [2:0] miao_shiwei ;
wire [3:0] fen_gewei ;
wire [2:0] fen_shiwei ;
wire [3:0] shi_gewei ;
wire [1:0] shi_shiwei ;
wire [3:0] day_gewei ;
wire [3:0] day_shiwei ;
wire [1:0] day_baiwei ;
wire [3:0] year_gewei ;
wire [3:0] year_shiwei ;
wire send_done ;
wire pi_flag ;
wire [7:0] pi_data ;
pll_125Mhz pll_125Mhz_inst (
.areset ( ~rst_n ),
.inclk0 ( clk ),
.c0 ( clk_125Mhz),
.locked ( locked )
);
b_code_gen
#(
.TIME_1S ( 32'd124_999_999),//32'd124_999_999
.TIME_10MS ( 32'd1_249_999 ),//32'd1_249_999
.TIME_8MS ( 32'd999_999 ),//32'd999_999
.TIME_5MS ( 32'd624_999 ),//32'd624_999
.TIME_2MS ( 32'd249_999 )//32'd249_999
)
b_code_gen_inst
(
.clk (clk_125Mhz),//125Mhz
.rst_n (locked ),
.ex_b_code (ex_b_code )
);
b_code
#(
.TIME_10MS ( 32'd1_249_999),//32'd1_249_999
.TIME_8MS ( 32'd999_999 ),//32'd999_999
.TIME_2MS ( 32'd249_999 ),//32'd249_999
.TIME_5MS ( 32'd624_999 ),//32'd624_999
.WUCHA_8US ( 32'd1000 ) //32'd1000
)
b_code_inst
(
.clk_125Mhz (clk_125Mhz ),
.rst_n (locked ),
.ex_b_code (ex_b_code ),
.miao_gewei (miao_gewei ),
.miao_shiwei (miao_shiwei),
.fen_gewei (fen_gewei ),
.fen_shiwei (fen_shiwei ),
.shi_gewei (shi_gewei ),
.shi_shiwei (shi_shiwei ),
.day_gewei (day_gewei ),
.day_shiwei (day_shiwei ),
.day_baiwei (day_baiwei ),
.year_gewei (year_gewei ),
.year_shiwei (year_shiwei)
);
fsm
#(
.TIME_1S (32'd124_999_999)//32'd124_999_999
)
fsm_inst
(
.clk (clk_125Mhz ),
.rst_n (locked ),
.send_done (send_done ),//控制串口发送信号线
.miao_gewei (miao_gewei ),
.miao_shiwei (miao_shiwei),
.fen_gewei (fen_gewei ),
.fen_shiwei (fen_shiwei ),
.shi_gewei (shi_gewei ),
.shi_shiwei (shi_shiwei ),
.day_gewei (day_gewei ),
.day_shiwei (day_shiwei ),
.day_baiwei (day_baiwei ),
.year_gewei (year_gewei ),
.year_shiwei (year_shiwei),
.pi_flag (pi_flag ),
.pi_data (pi_data )
);
uart_tx
#(
.CLK_FREQ ('d124_999_999),
.BPS ('d9600 )
)
uart_tx_inst
(
.clk (clk_125Mhz ) ,
.rst_n (locked ) ,
.pi_flag (pi_flag ) ,
.pi_data (pi_data ) ,
.send_done (send_done ) ,
.tx (tx )
);
endmodule
b_code_gen
module b_code_gen
#(
parameter TIME_1S = 32'd124_999_999,
parameter TIME_10MS = 32'd1_249_999 ,
parameter TIME_8MS = 32'd999_999 ,
parameter TIME_5MS = 32'd624_999 ,
parameter TIME_2MS = 32'd249_999
)
(
input wire clk ,//125Mhz
input wire rst_n ,
output reg ex_b_code
);
parameter idle = 8'd0;
parameter s0 = 8'd1;
parameter s1 = 8'd2;
parameter s2 = 8'd3;
parameter s3 = 8'd4;
parameter s4 = 8'd5;
parameter s5 = 8'd6;
//给3个基本码元类型编码
parameter MAYUAN_P = 8'h50;
parameter MAYUAN_0 = 8'h30;
parameter MAYUAN_1 = 8'h31;
parameter MAYUAN_NUM = 'd100;
//定义B码的一帧数据的数组,B码一帧数据有100个码元
wire [7:0] mem [99:0];
//26年154天12时59分48秒
assign mem[0] = MAYUAN_P;//位置分隔符
assign mem[1] = MAYUAN_P;
assign mem[2] = MAYUAN_0;//秒个位
assign mem[3] = MAYUAN_0;
assign mem[4] = MAYUAN_0;
assign mem[5] = MAYUAN_1;
assign mem[6] = MAYUAN_0;//索引标志,置0
assign mem[7] = MAYUAN_0;//秒十位
assign mem[8] = MAYUAN_0;
assign mem[9] = MAYUAN_1;
assign mem[10] = MAYUAN_P;//位置分隔符
assign mem[11] = MAYUAN_1;//分个位
assign mem[12] = MAYUAN_0;
assign mem[13] = MAYUAN_0;
assign mem[14] = MAYUAN_1;
assign mem[15] = MAYUAN_0;//索引标志,置0
assign mem[16] = MAYUAN_1;//分十位
assign mem[17] = MAYUAN_0;
assign mem[18] = MAYUAN_1;
assign mem[19] = MAYUAN_0;//保留,置0
assign mem[20] = MAYUAN_P;//位置分隔符
assign mem[21] = MAYUAN_0;//时个位
assign mem[22] = MAYUAN_1;
assign mem[23] = MAYUAN_0;
assign mem[24] = MAYUAN_0;
assign mem[25] = MAYUAN_0;//索引标志,置0
assign mem[26] = MAYUAN_1;//时十位
assign mem[27] = MAYUAN_0;
assign mem[28] = MAYUAN_0;//保留,置0
assign mem[29] = MAYUAN_0;//保留,置0
assign mem[30] = MAYUAN_P;//位置分隔符
assign mem[31] = MAYUAN_0;//日个位
assign mem[32] = MAYUAN_0;
assign mem[33] = MAYUAN_1;
assign mem[34] = MAYUAN_0;
assign mem[35] = MAYUAN_0;//索引标志,置0
assign mem[36] = MAYUAN_1;//日十位
assign mem[37] = MAYUAN_0;
assign mem[38] = MAYUAN_1;
assign mem[39] = MAYUAN_0;
assign mem[40] = MAYUAN_P;//位置分隔符
assign mem[41] = MAYUAN_1;//日百位
assign mem[42] = MAYUAN_0;
assign mem[43] = MAYUAN_0;//保留,置0
assign mem[44] = MAYUAN_0;//保留,置0
assign mem[45] = MAYUAN_0;//保留,置0
assign mem[46] = MAYUAN_0;//保留,置0
assign mem[47] = MAYUAN_0;//保留,置0
assign mem[48] = MAYUAN_0;//保留,置0
assign mem[49] = MAYUAN_0;//保留,置0
assign mem[50] = MAYUAN_P;//位置分隔符
assign mem[51] = MAYUAN_0;//年个位
assign mem[52] = MAYUAN_1;
assign mem[53] = MAYUAN_1;
assign mem[54] = MAYUAN_0;
assign mem[55] = MAYUAN_0;//索引标志,置0
assign mem[56] = MAYUAN_0;//年十位
assign mem[57] = MAYUAN_1;
assign mem[58] = MAYUAN_0;
assign mem[59] = MAYUAN_0;
assign mem[60] = MAYUAN_P;//p//位置分隔符
assign mem[61] = MAYUAN_0;//0//闰秒预告LSP
assign mem[62] = MAYUAN_0;//0//闰秒标志LS
assign mem[63] = MAYUAN_0;//0//夏制时预告DSP
assign mem[64] = MAYUAN_0;//0//夏制时标志DST
assign mem[65] = MAYUAN_0;//0//时间偏移符号位
assign mem[66] = MAYUAN_0;//0
assign mem[67] = MAYUAN_0;//0
assign mem[68] = MAYUAN_0;//0
assign mem[69] = MAYUAN_0;//0
assign mem[70] = MAYUAN_P;//p位置分隔符
assign mem[71] = MAYUAN_0;//0不增加时间偏移量
assign mem[72] = MAYUAN_0;//0正常工作状态
assign mem[73] = MAYUAN_0;//0正常工作状态
assign mem[74] = MAYUAN_0;//0正常工作状态
assign mem[75] = MAYUAN_0;//0正常工作状态
assign mem[76] = MAYUAN_1;//1(校验位)
assign mem[77] = MAYUAN_0;//0//保留,置0
assign mem[78] = MAYUAN_0;//0//保留,置0
assign mem[79] = MAYUAN_0;//0//保留,置0
assign mem[80] = MAYUAN_P;//位置分隔符
assign mem[81] = MAYUAN_0;//0 //一天中的秒数(二进制低9位)
assign mem[82] = MAYUAN_0;//0 //一天中的秒数86400
assign mem[83] = MAYUAN_0;//0
assign mem[84] = MAYUAN_0;//0
assign mem[85] = MAYUAN_0;//0
assign mem[86] = MAYUAN_0;//0
assign mem[87] = MAYUAN_0;//0
assign mem[88] = MAYUAN_1;//1
assign mem[89] = MAYUAN_1;//1
assign mem[90] = MAYUAN_P;//位置分隔符
assign mem[91] = MAYUAN_0;//0 //一天中的秒数(二进制高9位)
assign mem[92] = MAYUAN_0;//0
assign mem[93] = MAYUAN_0;//0
assign mem[94] = MAYUAN_1;//1
assign mem[95] = MAYUAN_0;//0
assign mem[96] = MAYUAN_1;//1
assign mem[97] = MAYUAN_0;//0
assign mem[98] = MAYUAN_1;//1
assign mem[99] = MAYUAN_0;//0
reg [7:0] state ;
reg [31:0] cnt_10ms ;
reg [7:0] index ;
reg [7:0] cnt_mayuan ;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
state <= idle;
cnt_10ms <= 32'd0;
index <= 8'd0;
cnt_mayuan <= 8'd0;
ex_b_code <= 1'b0;
end
else
case(state)
idle:
begin
state <= s0;
cnt_10ms <= 32'd0;
index <= 8'd0;
cnt_mayuan <= 8'd0;
ex_b_code <= 1'b0;
end
s0 :
begin
if(mem[index] == MAYUAN_P)
state <= s1;
else if(mem[index] == MAYUAN_0)
state <= s2;
else// if(mem[index] == MAYUAN_1)
state <= s3;
end
s1 :
begin
if(cnt_10ms == TIME_10MS)
begin
state <= s4;
cnt_10ms <= 32'd0;
end
else if(cnt_10ms <= TIME_8MS)
begin
ex_b_code <= 1'b1;
cnt_10ms <= cnt_10ms + 1'b1;
end
else
begin
ex_b_code <= 1'b0;
cnt_10ms <= cnt_10ms + 1'b1;
end
end
s2 :
begin
if(cnt_10ms == TIME_10MS)
begin
state <= s4;
cnt_10ms <= 32'd0;
end
else if(cnt_10ms <= TIME_2MS)
begin
ex_b_code <= 1'b1;
cnt_10ms <= cnt_10ms + 1'b1;
end
else
begin
ex_b_code <= 1'b0;
cnt_10ms <= cnt_10ms + 1'b1;
end
end
s3 :
begin
if(cnt_10ms == TIME_10MS)
begin
state <= s4;
cnt_10ms <= 32'd0;
end
else if(cnt_10ms <= TIME_5MS)
begin
ex_b_code <= 1'b1;
cnt_10ms <= cnt_10ms + 1'b1;
end
else
begin
ex_b_code <= 1'b0;
cnt_10ms <= cnt_10ms + 1'b1;
end
end
s4 :
begin
index <= index + 1'b1;
cnt_mayuan <= cnt_mayuan + 1'b1;
state <= s5;
end
s5 :
begin
if(cnt_mayuan == MAYUAN_NUM)
state <= idle;
else
state <= s0;
end
default:
begin
state <= idle;
cnt_10ms <= 32'd0;
index <= 8'd0;
cnt_mayuan <= 8'd0;
ex_b_code <= 1'b0;
end
endcase
end
endmodule
b_code
module b_code
#(
parameter TIME_10MS = 32'd1_249_999,
parameter TIME_8MS = 32'd999_999 ,
parameter TIME_2MS = 32'd249_999 ,
parameter TIME_5MS = 32'd629_999 ,
parameter WUCHA_8US = 32'd1000
)
(
input wire clk_125Mhz ,
input wire rst_n ,
input wire ex_b_code ,
output reg [3:0] miao_gewei ,
output reg [2:0] miao_shiwei ,
output reg [3:0] fen_gewei ,
output reg [2:0] fen_shiwei ,
output reg [3:0] shi_gewei ,
output reg [1:0] shi_shiwei ,
output reg [3:0] day_gewei ,
output reg [3:0] day_shiwei ,
output reg [1:0] day_baiwei ,
output reg [3:0] year_gewei ,
output reg [3:0] year_shiwei
);
// 消除ex_b_code亚稳态,提高信号质量
reg ex_b_code_0;
reg ex_b_code_1;
reg ex_b_code_2;
reg fall_0 ;//用于确定当前码元类型(now_type)
reg fall_1 ;//同时有锁定的码元类型(latch_type)和当前码元类型(now_type),用于开始信号双p检测
reg fall_2 ;//更新锁定的上一个码元信息(latch_type)
reg fall_3 ;//用于定位一帧数据中当前码元对应的序号
reg fall_4 ;//用于完成当前码元的时间信息解析
reg fall_5 ;//用于全部解析完成的整体输出
reg fall_6 ;//预留
reg fall_7 ;//用于高电平计数器计数值的清零(高电平计数器:计数高电平保持时常确定码元)
reg [31:0] cnt_b ;
reg [1:0] now_type ;
reg work_state ;
reg [1:0] latch_type ;
reg [7:0] cnt_mem ;
// 多级打拍处理,消除ex_b_code亚稳态,提高信号质量,下降沿检测
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
begin
ex_b_code_0 <= 1'b0;
ex_b_code_1 <= 1'b0;
ex_b_code_2 <= 1'b0;
fall_0 <= 1'b0;
fall_1 <= 1'b0;
fall_2 <= 1'b0;
fall_3 <= 1'b0;
fall_4 <= 1'b0;
fall_5 <= 1'b0;
fall_6 <= 1'b0;
fall_7 <= 1'b0;
end
else
begin
ex_b_code_0 <= ex_b_code ;
ex_b_code_1 <= ex_b_code_0 ;
ex_b_code_2 <= ex_b_code_1 ;
fall_0 <= ~ex_b_code_1 && ex_b_code_2;
fall_1 <= fall_0 ;
fall_2 <= fall_1 ;
fall_3 <= fall_2 ;
fall_4 <= fall_3 ;
fall_5 <= fall_4 ;
fall_6 <= fall_5 ;
fall_7 <= fall_6 ;
end
end
// cnt_b:高电平计数器,低电平保持,fall_7清零
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
cnt_b <= 32'd0;
else if(fall_7)//注意优先级
cnt_b <= 32'd0;
else if(ex_b_code_2)
cnt_b <= cnt_b + 1'b1;
else
cnt_b <= cnt_b;
end
// now_type:当前码元类型 0码:00;1码:01;p码:10
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
now_type <= 2'b11 ;
else if(fall_0 && TIME_8MS - WUCHA_8US <= cnt_b && cnt_b <= TIME_8MS + WUCHA_8US)
now_type <= 2'b10 ;//p
else if(fall_0 && TIME_5MS - WUCHA_8US <= cnt_b && cnt_b <= TIME_5MS + WUCHA_8US)
now_type <= 2'b01 ;//1
else if(fall_0 && TIME_2MS - WUCHA_8US <= cnt_b && cnt_b <= TIME_2MS + WUCHA_8US)
now_type <= 2'b00 ;//0
else if(fall_0)
now_type <= 2'b11 ;//出现错码
else
now_type <= now_type;
end
// latch_type:锁定上一个码元
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
latch_type <= 2'b11 ;
else if(fall_2)
latch_type <= now_type ;
else
latch_type <= latch_type;
end
// work_state:工作状态(双p检测)
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
work_state <= 1'b0;
else if(fall_1 && now_type == 2'b10 && latch_type == 2'b10)
work_state <= 1'b1;
else if(cnt_mem == 8'd61)
work_state <= 1'b0;
else
work_state <= work_state;
end
// cnt_mem:码元序号
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
cnt_mem <= 8'd0;
else if(~work_state)
cnt_mem <= 8'd0;
else if(fall_3)
cnt_mem <= cnt_mem + 1'b1;
else
cnt_mem <= cnt_mem;
end
// 时间输出寄存器(为了统一输出时间)
reg [3:0] miao_gewei_r ;
reg [2:0] miao_shiwei_r;
reg [3:0] fen_gewei_r ;
reg [2:0] fen_shiwei_r ;
reg [3:0] shi_gewei_r ;
reg [1:0] shi_shiwei_r ;
reg [3:0] day_gewei_r ;
reg [3:0] day_shiwei_r ;
reg [1:0] day_baiwei_r ;
reg [3:0] year_gewei_r ;
reg [3:0] year_shiwei_r;
/////////////秒个位时间信息 序号2~5 miao_gewei_r
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
miao_gewei_r <= 4'd0;
else if(fall_4 && 8'd2 <= cnt_mem && cnt_mem <= 8'd5)
miao_gewei_r <= {now_type[0],miao_gewei_r[3:1]};
else
miao_gewei_r <= miao_gewei_r;
end
/////////////秒十位时间信息 序号7~9 miao_shiwei_r
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
miao_shiwei_r <= 3'd0;
else if(fall_4 && 8'd7 <= cnt_mem && cnt_mem <= 8'd9)
miao_shiwei_r <= {now_type[0],miao_shiwei_r[2:1]};
else
miao_shiwei_r <= miao_shiwei_r;
end
/////////////分个位时间信息 序号11~14 fen_gewei_r
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
fen_gewei_r <= 4'd0;
else if(fall_4 && 8'd11 <= cnt_mem && cnt_mem <= 8'd14)
fen_gewei_r <= {now_type[0],fen_gewei_r[3:1]};
else
fen_gewei_r <= fen_gewei_r;
end
/////////////分十位时间信息 序号16~18 fen_shiwei_r
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
fen_shiwei_r <= 3'd0;
else if(fall_4 && 8'd16 <= cnt_mem && cnt_mem <= 8'd18)
fen_shiwei_r <= {now_type[0],fen_shiwei_r[2:1]};
else
fen_shiwei_r <= fen_shiwei_r;
end
/////////////时个位时间信息 序号21~24 shi_gewei_r
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
shi_gewei_r <= 4'd0;
else if(fall_4 && 8'd21 <= cnt_mem && cnt_mem <= 8'd24)
shi_gewei_r <= {now_type[0],shi_gewei_r[3:1]};
else
shi_gewei_r <= shi_gewei_r;
end
/////////////时十位时间信息 序号26~27 shi_shiwei_r
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
shi_shiwei_r <= 2'd0;
else if(fall_4 && 8'd26 <= cnt_mem && cnt_mem <= 8'd27)
shi_shiwei_r <= {now_type[0],shi_shiwei_r[1]};
else
shi_shiwei_r <= shi_shiwei_r;
end
/////////////日个位时间信息 序号31~34 day_gewei_r
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
day_gewei_r <= 4'd0;
else if(fall_4 && 8'd31 <= cnt_mem && cnt_mem <= 8'd34)
day_gewei_r <= {now_type[0],day_gewei_r[3:1]};
else
day_gewei_r <= day_gewei_r;
end
/////////////日十位时间信息 序号36~39 day_shiwei_r
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
day_shiwei_r <= 4'd0;
else if(fall_4 && 8'd36 <= cnt_mem && cnt_mem <= 8'd39)
day_shiwei_r <= {now_type[0],day_shiwei_r[3:1]};
else
day_shiwei_r <= day_shiwei_r;
end
/////////////日百位时间信息 序号41~42 day_baiwei_r
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
day_baiwei_r <= 2'd0;
else if(fall_4 && 8'd41 <= cnt_mem && cnt_mem <= 8'd42)
day_baiwei_r <= {now_type[0],day_baiwei_r[1]};
else
day_baiwei_r <= day_baiwei_r;
end
/////////////年个位时间信息 序号51~54 year_gewei_r
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
year_gewei_r <= 4'd0;
else if(fall_4 && 8'd51 <= cnt_mem && cnt_mem <= 8'd54)
year_gewei_r <= {now_type[0],year_gewei_r[3:1]};
else
year_gewei_r <= year_gewei_r;
end
/////////////年十位时间信息 序号56~59 year_shiwei_r
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
year_shiwei_r <= 4'd0;
else if(fall_4 && 8'd56 <= cnt_mem && cnt_mem <= 8'd59)
year_shiwei_r <= {now_type[0],year_shiwei_r[3:1]};
else
year_shiwei_r <= year_shiwei_r;
end
/////////////////////////////////////////////////////////////
// 统一输出
always@(posedge clk_125Mhz or negedge rst_n)
begin
if(!rst_n)
begin
miao_gewei <= 4'd0;
miao_shiwei <= 3'd0;
fen_gewei <= 4'd0;
fen_shiwei <= 3'd0;
shi_gewei <= 4'd0;
shi_shiwei <= 2'd0;
day_gewei <= 4'd0;
day_shiwei <= 4'd0;
day_baiwei <= 2'd0;
year_gewei <= 4'd0;
year_shiwei <= 4'd0;
end
else if(fall_5 && cnt_mem == 8'd60)
begin
miao_gewei <= miao_gewei_r ;
miao_shiwei <= miao_shiwei_r;
fen_gewei <= fen_gewei_r ;
fen_shiwei <= fen_shiwei_r ;
shi_gewei <= shi_gewei_r ;
shi_shiwei <= shi_shiwei_r ;
day_gewei <= day_gewei_r ;
day_shiwei <= day_shiwei_r ;
day_baiwei <= day_baiwei_r ;
year_gewei <= year_gewei_r ;
year_shiwei <= year_shiwei_r;
end
else
begin
miao_gewei <= miao_gewei ;
miao_shiwei <= miao_shiwei ;
fen_gewei <= fen_gewei ;
fen_shiwei <= fen_shiwei ;
shi_gewei <= shi_gewei ;
shi_shiwei <= shi_shiwei ;
day_gewei <= day_gewei ;
day_shiwei <= day_shiwei ;
day_baiwei <= day_baiwei ;
year_gewei <= year_gewei ;
year_shiwei <= year_shiwei ;
end
end
endmodule
fsm
module fsm
#(
parameter TIME_1S = 32'd50_000_000
)
(
input wire clk ,
input wire rst_n ,
input wire send_done ,//控制串口发送信号线
input wire [3:0] miao_gewei ,
input wire [2:0] miao_shiwei ,
input wire [3:0] fen_gewei ,
input wire [2:0] fen_shiwei ,
input wire [3:0] shi_gewei ,
input wire [1:0] shi_shiwei ,
input wire [3:0] day_gewei ,
input wire [3:0] day_shiwei ,
input wire [1:0] day_baiwei ,
input wire [3:0] year_gewei ,
input wire [3:0] year_shiwei ,
output reg pi_flag ,
output reg [7:0] pi_data
);
//parameter TIME_1S = 32'd50_000;//用于仿真测试,缩短仿真时间
parameter BYTE_NUM = 32'd14 ;//发送的字节数
parameter idle = 8'd0;
parameter s0 = 8'd1;
parameter s1 = 8'd2;
parameter s2 = 8'd3;
parameter s3 = 8'd4;
//定义一个数组,存放8个字节需要发送的数据
wire [7:0] mem [0:13];
assign mem[0] = 8'h55;//帧头
assign mem[1] = 8'h55;
assign mem[2] = 8'h55;
assign mem[3] = {4'd0,miao_gewei [3:0] };//秒个位,1个字节
assign mem[4] = {5'd0,miao_shiwei [2:0] };//秒十位,1个字节
assign mem[5] = {4'd0,fen_gewei [3:0]};//分个位,1个字节
assign mem[6] = {5'd0,fen_shiwei [2:0]};//分十位,1个字节
assign mem[7] = {4'd0,shi_gewei [3:0]};//时个位,1个字节
assign mem[8] = {6'd0,shi_shiwei [1:0]};//时十位,1个字节
assign mem[9] = {4'd0,day_gewei [3:0]};//天个位,1个字节
assign mem[10] = {4'd0,day_shiwei [3:0]};//天十位,1个字节
assign mem[11] = {6'd0,day_baiwei [1:0]};//天百位,1个字节
assign mem[12] = {4'd0,year_gewei [3:0]};//年个位,1个字节
assign mem[13] = {4'd0,year_shiwei [3:0]};//年十位,1个字节
reg [7:0] state;
//内部变量的定义
reg [31:0] delay_cnt;
reg [7:0] send_done_cnt;
reg [7:0] index;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
delay_cnt <= 32'd0;
send_done_cnt <= 8'd0;
index <= 8'd0;
state <= idle;
pi_flag <= 1'b0;
pi_data <= 8'd0;
end
else
begin
case(state)
idle:
begin
if(delay_cnt == TIME_1S)
begin
delay_cnt <= 32'd0;
send_done_cnt <= 8'd0;
pi_flag <= 1'b0;
pi_data <= 8'd0;
index <= 8'd0;
state <= s0 ;
end
else
begin
state <= state;
delay_cnt <= delay_cnt + 1'b1;
end
end
s0 :
begin
pi_flag <= 1'b1;
pi_data <= mem[index];
state <= s1;
end
s1 :
begin
pi_flag <= 1'b0;
if(send_done)
begin
state <= s2;
send_done_cnt <= send_done_cnt + 1'b1;
index <= index + 1'b1;
end
else
begin
state <= state;
send_done_cnt <= send_done_cnt;
index <= index;
end
end
s2 :
begin
if(send_done_cnt == BYTE_NUM)
state <= s3;
else
state <= s0;
end
s3 :
begin
delay_cnt <= 32'd0;
send_done_cnt <= 8'd0;
index <= 8'd0;
state <= idle;
pi_flag <= 1'b0;
pi_data <= 8'd0;
end
default:
begin
delay_cnt <= 32'd0;
send_done_cnt <= 8'd0;
index <= 8'd0;
state <= idle;
pi_flag <= 1'b0;
pi_data <= 8'd0;
end
endcase
end
end
endmodule
uart_tx
module uart_tx
#(
parameter CLK_FREQ = 'd124_999_999 ,
parameter BPS = 'd9600
)
(
input wire clk ,
input wire rst_n ,
input wire pi_flag ,
input wire [7:0] pi_data ,
output reg send_done ,
output reg tx
);
localparam BAUD_TIME= CLK_FREQ / BPS ;
parameter idle = 8'd0 ;
parameter s0 = 8'd1 ;
parameter s1 = 8'd2 ;
parameter s2 = 8'd3 ;
parameter s3 = 8'd4 ;
parameter s4 = 8'd5 ;
parameter s5 = 8'd6 ;
parameter s6 = 8'd7 ;
parameter s7 = 8'd8 ;
parameter s8 = 8'd9 ;
parameter s9 = 8'd10;
parameter s10 = 8'd11;
parameter done = 8'd12;
reg [7:0] state ;
reg [15:0] delay_cnt ;
reg [9:0] send_data ;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
state <= idle;
delay_cnt <= 16'd0;
send_done <= 1'b0;
tx <= 1'b1;
send_data <= 10'd0;
end
else
case(state)
idle:
begin
if(pi_flag)
state <= s0;
else
state <= state;
delay_cnt <= 16'd0;
tx <= 1'b1;
send_done <= 1'b0;
end
s0 :
begin
send_data <= {1'b1,pi_data[7:0],1'b0};
state <= s1;
end
s1 :
begin
if(delay_cnt == BAUD_TIME - 1'b1)
begin
state <= s2;
delay_cnt <= 16'd0;
end
else
begin
tx <= send_data[0];
delay_cnt <= delay_cnt + 1'b1;
end
end
s2 :
begin
if(delay_cnt == BAUD_TIME - 1'b1)
begin
state <= s3;
delay_cnt <= 16'd0;
end
else
begin
tx <= send_data[1];
delay_cnt <= delay_cnt + 1'b1;
end
end
s3 :
begin
if(delay_cnt == BAUD_TIME - 1'b1)
begin
state <= s4;
delay_cnt <= 16'd0;
end
else
begin
tx <= send_data[2];
delay_cnt <= delay_cnt + 1'b1;
end
end
s4 :
begin
if(delay_cnt == BAUD_TIME - 1'b1)
begin
state <= s5;
delay_cnt <= 16'd0;
end
else
begin
tx <= send_data[3];
delay_cnt <= delay_cnt + 1'b1;
end
end
s5 :
begin
if(delay_cnt == BAUD_TIME - 1'b1)
begin
state <= s6;
delay_cnt <= 16'd0;
end
else
begin
tx <= send_data[4];
delay_cnt <= delay_cnt + 1'b1;
end
end
s6 :
begin
if(delay_cnt == BAUD_TIME - 1'b1)
begin
state <= s7;
delay_cnt <= 16'd0;
end
else
begin
tx <= send_data[5];
delay_cnt <= delay_cnt + 1'b1;
end
end
s7 :
begin
if(delay_cnt == BAUD_TIME - 1'b1)
begin
state <= s8;
delay_cnt <= 16'd0;
end
else
begin
tx <= send_data[6];
delay_cnt <= delay_cnt + 1'b1;
end
end
s8 :
begin
if(delay_cnt == BAUD_TIME - 1'b1)
begin
state <= s9;
delay_cnt <= 16'd0;
end
else
begin
tx <= send_data[7];
delay_cnt <= delay_cnt + 1'b1;
end
end
s9 :
begin
if(delay_cnt == BAUD_TIME - 1'b1)
begin
state <= s10;
delay_cnt <= 16'd0;
end
else
begin
tx <= send_data[8];
delay_cnt <= delay_cnt + 1'b1;
end
end
s10 :
begin
if(delay_cnt == BAUD_TIME - 1'b1)
begin
state <= done;
delay_cnt <= 16'd0;
end
else
begin
tx <= send_data[9];
delay_cnt <= delay_cnt + 1'b1;
end
end
done:
begin
state <= idle;
send_done <= 1'b1;
end
default:
begin
state <= idle;
delay_cnt <= 16'd0;
send_done <= 1'b0;
tx <= 1'b1;
end
endcase
end
endmodule
编写仿真代码
`timescale 1ns/1ps
module uart_send_IRIG_data_top_tb();
reg clk ;
reg rst_n ;
initial
begin
clk = 1'b0;
rst_n = 1'b0;
#123
rst_n = 1'b1;
end
always #10 clk = ~clk;
defparam uart_send_IRIG_data_top_inst.b_code_gen_inst.TIME_1S = 32'd124_999;
defparam uart_send_IRIG_data_top_inst.b_code_gen_inst.TIME_10MS = 32'd1_249 ;
defparam uart_send_IRIG_data_top_inst.b_code_gen_inst.TIME_8MS = 32'd999 ;
defparam uart_send_IRIG_data_top_inst.b_code_gen_inst.TIME_5MS = 32'd624 ;
defparam uart_send_IRIG_data_top_inst.b_code_gen_inst.TIME_2MS = 32'd249 ;
defparam uart_send_IRIG_data_top_inst.b_code_inst.TIME_10MS = 32'd1_249;
defparam uart_send_IRIG_data_top_inst.b_code_inst.TIME_8MS = 32'd999 ;
defparam uart_send_IRIG_data_top_inst.b_code_inst.TIME_2MS = 32'd249 ;
defparam uart_send_IRIG_data_top_inst.b_code_inst.TIME_5MS = 32'd624 ;
defparam uart_send_IRIG_data_top_inst.b_code_inst.WUCHA_8US = 32'd10 ;
defparam uart_send_IRIG_data_top_inst.fsm_inst.TIME_1S = 32'd124_999;
defparam uart_send_IRIG_data_top_inst.uart_tx_inst.CLK_FREQ = 'd124_999_999;
defparam uart_send_IRIG_data_top_inst.uart_tx_inst.BPS = 'd9600 ;
uart_send_IRIG_data_top uart_send_IRIG_data_top_inst(
.clk (clk ),
.rst_n (rst_n ),
.tx ()
);
endmodule
仿真验证

可以看出顶层没问题。
上板验证
