fpga串口打印计数值作业
作业4:
在前面第六讲作业3的基础上(带按键消抖的计数器流水灯作业作业3),实现功能:
当按键1操作时,向串口发送按键的编号,以及按键时6位计数器的数值大小。发送的内容为:“NO.按键编号+Times.按键次数”,例如:“NO.1+Times.5”.
当按键2操作时,向串口发送按键的编号,以及按键后6位计数器的数值大小。发送内容同上。
思路:计数值传递,数据+48转为ASC码赋给串口数据存储器。
具体代码如下(复制黏贴都有点累):九个文件
seg_test.v // 顶层文件
uart_test.v
uart_rx.v
uart_tx.v
seg_scan.v
led_test.v
seg_decoder.v
key_debounce.v
count_m10.v
//seg_test.v
`timescale 1ns / 1ps
//*******************************************************************************/
module seg_test(
input clk,
input rst_n,
output[5:0]seg_sel,
output[7:0]seg_data,
input [1:0] key,
output [3:0] led,
input uart_rx,
output uart_tx
);
reg[31:0] timer_cnt;
reg en_1hz; //1 second , 1 counter enable
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
en_1hz <= 1'b0;
timer_cnt <= 32'd0;
end
else if(timer_cnt >= 32'd49_999_999)
begin
en_1hz <= 1'b1;
timer_cnt <= 32'd0;
end
else
begin
en_1hz <= 1'b0;
timer_cnt <= timer_cnt + 32'd1;
end
end
wire [1:0]button_negedge; //Key falling edge
key_debounce key_debounce_1(
.clk (clk),
.rst (~rst_n),
.button_in (key[0]),
.button_posedge (),
.button_negedge (button_negedge[0]),
.button_out ()
);
key_debounce key_debounce_2(
.clk (clk),
.rst (~rst_n),
.button_in (key[1]),
.button_posedge (),
.button_negedge (button_negedge[1]),
.button_out ()
);
led_test led_test0
(
.clk (clk), // system clock 50Mhz on board
.rst_n (rst_n), // reset ,low active
.key_out (button_negedge),
.led (led) // LED,use for control the LED signal on board
);
uart_test uart_test0
(
.clk (clk), // system clock 50Mhz on board
.rst_n (rst_n), // reset ,low active
.uart_rx (uart_rx),
.uart_tx (uart_tx),
.key_out (button_negedge),
.count0 (count0),
.count1 (count1),
.count2 (count2),
.count3 (count3),
.count4 (count4),
.count5 (count5)
);
wire[3:0] count0;
wire t0;
count_m10 count10_m0(
.clk (clk),
.rst_n (rst_n),
.en (en_1hz),
.clr (1'b0),
.key (button_negedge),
.data (count0),
.t (t0)
);
wire[3:0] count1;
wire t1;
count_m10 count10_m1(
.clk (clk),
.rst_n (rst_n),
.en (t0),
.clr (1'b0),
.key (2'b0),
.data (count1),
.t (t1)
);
wire[3:0] count2;
wire t2;
count_m10 count10_m2(
.clk (clk),
.rst_n (rst_n),
.en (t1),
.clr (1'b0),
.key (2'b0),
.data (count2),
.t (t2)
);
wire[3:0] count3;
wire t3;
count_m10 count10_m3(
.clk (clk),
.rst_n (rst_n),
.en (t2),
.clr (1'b0),
.key (2'b0),
.data (count3),
.t (t3)
);
wire[3:0] count4;
wire t4;
count_m10 count10_m4(
.clk (clk),
.rst_n (rst_n),
.en (t3),
.clr (1'b0),
.key (2'b0),
.data (count4),
.t (t4)
);
wire[3:0] count5;
wire t5;
count_m10 count10_m5(
.clk (clk),
.rst_n (rst_n),
.en (t4),
.clr (1'b0),
.key (2'b0),
.data (count5),
.t (t5)
);
wire[6:0] seg_data_0;
seg_decoder seg_decoder_m0(
.bin_data (count5),
.seg_data (seg_data_0)
);
wire[6:0] seg_data_1;
seg_decoder seg_decoder_m1(
.bin_data (count4),
.seg_data (seg_data_1)
);
wire[6:0] seg_data_2;
seg_decoder seg_decoder_m2(
.bin_data (count3),
.seg_data (seg_data_2)
);
wire[6:0] seg_data_3;
seg_decoder seg_decoder_m3(
.bin_data (count2),
.seg_data (seg_data_3)
);
wire[6:0] seg_data_4;
seg_decoder seg_decoder_m4(
.bin_data (count1),
.seg_data (seg_data_4)
);
wire[6:0] seg_data_5;
seg_decoder seg_decoder_m5(
.bin_data (count0),
.seg_data (seg_data_5)
);
seg_scan seg_scan_m0(
.clk (clk),
.rst_n (rst_n),
.seg_sel (seg_sel),
.seg_data (seg_data),
.seg_data_0 ({1'b1,seg_data_0}), //The decimal point at the highest bit,and low level effecitve
.seg_data_1 ({1'b1,seg_data_1}),
.seg_data_2 ({1'b1,seg_data_2}),
.seg_data_3 ({1'b1,seg_data_3}),
.seg_data_4 ({1'b1,seg_data_4}),
.seg_data_5 ({1'b1,seg_data_5})
);
endmodule
//seg_scan.v
module seg_scan(
input clk,
input rst_n,
output reg[5:0] seg_sel, //digital led chip select
output reg[7:0] seg_data, //eight segment digital tube output,MSB is the decimal point
input[7:0] seg_data_0,
input[7:0] seg_data_1,
input[7:0] seg_data_2,
input[7:0] seg_data_3,
input[7:0] seg_data_4,
input[7:0] seg_data_5
);
parameter SCAN_FREQ = 200; //scan frequency
parameter CLK_FREQ = 50000000; //clock frequency
parameter SCAN_COUNT = CLK_FREQ /(SCAN_FREQ * 6) - 1;
reg[31:0] scan_timer; //scan time counter
reg[3:0] scan_sel; //Scan select counter
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
scan_timer <= 32'd0;
scan_sel <= 4'd0;
end
else if(scan_timer >= SCAN_COUNT)
begin
scan_timer <= 32'd0;
if(scan_sel == 4'd5)
scan_sel <= 4'd0;
else
scan_sel <= scan_sel + 4'd1;
end
else
begin
scan_timer <= scan_timer + 32'd1;
end
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
seg_sel <= 6'b111111;
seg_data <= 8'hff;
end
else
begin
case(scan_sel)
//first digital led
4'd0:
begin
seg_sel <= 6'b11_1110;
seg_data <= seg_data_0;
end
//second digital led
4'd1:
begin
seg_sel <= 6'b11_1101;
seg_data <= seg_data_1;
end
//...
4'd2:
begin
seg_sel <= 6'b11_1011;
seg_data <= seg_data_2;
end
4'd3:
begin
seg_sel <= 6'b11_0111;
seg_data <= seg_data_3;
end
4'd4:
begin
seg_sel <= 6'b10_1111;
seg_data <= seg_data_4;
end
4'd5:
begin
seg_sel <= 6'b01_1111;
seg_data <= seg_data_5;
end
default:
begin
seg_sel <= 6'b11_1111;
seg_data <= 8'hff;
end
endcase
end
end
endmodule
//seg_decoder.v
//*************************************************************************/
module seg_decoder
(
input[3:0] bin_data, // bin data input
output reg[6:0] seg_data // seven segments LED output
);
always@(*)
begin
case(bin_data)
4'd0:seg_data <= 7'b100_0000;
4'd1:seg_data <= 7'b111_1001;
4'd2:seg_data <= 7'b010_0100;
4'd3:seg_data <= 7'b011_0000;
4'd4:seg_data <= 7'b001_1001;
4'd5:seg_data <= 7'b001_0010;
4'd6:seg_data <= 7'b000_0010;
4'd7:seg_data <= 7'b111_1000;
4'd8:seg_data <= 7'b000_0000;
4'd9:seg_data <= 7'b001_0000;
4'ha:seg_data <= 7'b000_1000;
4'hb:seg_data <= 7'b000_0011;
4'hc:seg_data <= 7'b100_0110;
4'hd:seg_data <= 7'b010_0001;
4'he:seg_data <= 7'b000_0110;
4'hf:seg_data <= 7'b000_1110;
default:seg_data <= 7'b111_1111;
endcase
end
endmodule
//led_test.v
module led_test
(
input clk, // system clock 50Mhz on board
input rst_n, // reset ,low active
input [1:0] key_out,
output reg[3:0] led // LED,use for control the LED signal on board
);
//define the time counter
reg [31:0] timer;
reg [3:0] count;
///按键
reg [0:0] flag;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
flag <= 1'd0;
else if (key_out==1'd1)
flag <= ~flag;
end
流水灯/
always@(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
timer <= 32'd0;
else if(timer == 32'd49_999_999)
timer <= 32'd0;
else
timer <= timer + 32'd1;
end
// LED control
always@(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
begin
led <= 4'b0000;
count <= 4'd0;
end
else if (flag == 0)
begin
if (timer == 32'd0)
led <= 4'b0001;
else if (timer == 32'd12_499_999)
led <= 4'b0010;
else if (timer == 32'd24_999_999)
led <= 4'b0100;
else if (timer == 32'd37_499_999)
led <= 4'b1000;
else if (timer == 32'd49_999_999)
led <= 4'b0000;
end
else
begin
if (timer == 32'd0)
led <= 4'b0000;
else if(timer == 32'd24_999_999)
led <= 4'b1111;
end
end
endmodule
//key_debounce.v
`timescale 1 ns / 100 ps
module key_debounce
(
input clk,
input rst,
input button_in,
output reg button_posedge,
output reg button_negedge,
output reg button_out
);
---------------- internal constants --------------
parameter N = 32 ; // debounce timer bitwidth
parameter FREQ = 50; //model clock :Mhz
parameter MAX_TIME = 20; //ms
localparam TIMER_MAX_VAL = MAX_TIME * 1000 * FREQ;
---------------- internal variables ---------------
reg [N-1 : 0] q_reg; // timing regs
reg [N-1 : 0] q_next;
reg DFF1, DFF2; // input flip-flops
wire q_add; // control flags
wire q_reset;
reg button_out_d0;
------------------------------------------------------
contenious assignment for counter control
assign q_reset = (DFF1 ^ DFF2); // xor input flip flops to look for level chage to reset counter
assign q_add = ~(q_reg == TIMER_MAX_VAL); // add to counter when q_reg msb is equal to 0
combo counter to manage q_next
always @ ( q_reset, q_add, q_reg)
begin
case( {q_reset , q_add})
2'b00 :
q_next <= q_reg;
2'b01 :
q_next <= q_reg + 1;
default :
q_next <= { N {1'b0} };
endcase
end
Flip flop inputs and q_reg update
always @ ( posedge clk or posedge rst)
begin
if(rst == 1'b1)
begin
DFF1 <= 1'b0;
DFF2 <= 1'b0;
q_reg <= { N {1'b0} };
end
else
begin
DFF1 <= button_in;
DFF2 <= DFF1;
q_reg <= q_next;
end
end
counter control
always @ ( posedge clk or posedge rst)
begin
if(rst == 1'b1)
button_out <= 1'b1;
else if(q_reg == TIMER_MAX_VAL)
button_out <= DFF2;
else
button_out <= button_out;
end
always @ ( posedge clk or posedge rst)
begin
if(rst == 1'b1)
begin
button_out_d0 <= 1'b1;
button_posedge <= 1'b0;
button_negedge <= 1'b0;
end
else
begin
button_out_d0 <= button_out;
button_posedge <= ~button_out_d0 & button_out;
button_negedge <= button_out_d0 & ~button_out;
end
end
endmodule
//count_m10.v
module count_m10(
input clk,
input rst_n,
input en, //Counter enable
input clr, //Counter synchronous reset
input [1:0] key,
output reg[3:0]data, //counter value
output reg t // carry enable signal
);
/
按键防抖
reg [0:0] flag;
reg [0:0] flag2;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin flag <= 1'd0;
// flag2 <= 1'd0;
end
else if (key[0]==1)
flag <= ~flag; //按键1标志位
end
///count_10m///
always@(posedge clk or negedge rst_n)
begin
if(rst_n==0)
begin
data <= 4'd0;
t <= 1'd0; flag2 <= 1'd0;
end
else if(clr)
begin
data <= 4'd0;
t <= 1'd0;
end
else if(key[1]==1)
flag2 <= ~flag2; //按键2标志位
else if(en) //1秒钟使能一次,计数en_1hz满
begin
if(data==4'd9)
begin
t<= 1'b1; //进位使能,data满9,前一位使能可以执行一次操作:data+1
data <= 4'd0;
end
********改动部分**********///
else
begin
if ((flag == 0)&&(flag2 == 0)) //按键1和2,有一个按下就停止计数
begin
data <= data + 4'd1;
t <= 1'b0;end
else
begin
if (flag2 == 1) //按键2标志位
begin
t<= 1'b1;
flag2 <= ~flag2;
end
else
t <= 1'b0;
end
end
end
else
t <= 1'b0;
end
endmodule
//uart_test.v
module uart_test(
input clk,
input rst_n,
input uart_rx,
output uart_tx,
input [1:0] key_out,
input [3:0] count0,
input [3:0] count1,
input [3:0] count2,
input [3:0] count3,
input [3:0] count4,
input [3:0] count5
);
parameter CLK_FRE = 50;//Mhz
localparam IDLE = 0;
localparam SEND = 1; //send HELLO ALINX\r\n
localparam WAIT = 2; //wait 1 second and send uart received data
reg[7:0] tx_data;
reg[7:0] tx_str;
reg tx_data_valid;
wire tx_data_ready;
reg[7:0] tx_cnt;
wire[7:0] rx_data;
wire rx_data_valid;
wire rx_data_ready;
reg[31:0] wait_cnt;
reg[3:0] state;
assign rx_data_ready = 1'b1;//always can receive data,
//if HELLO ALINX\r\n is being sent, the received data is discarded
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
wait_cnt <= 32'd0;
tx_data <= 8'd0;
state <= IDLE;
tx_cnt <= 8'd0;
tx_data_valid <= 1'b0;
end
else
begin
case(state)
IDLE:if(flag1 || flag2)
state <= SEND;
SEND:
begin
wait_cnt <= 32'd0;
tx_data <= tx_str;
if(tx_data_valid == 1'b1 && tx_data_ready == 1'b1 && tx_cnt < 8'd15)//Send x bytes data
begin
tx_cnt <= tx_cnt + 8'd1; //Send data counter
end
else if(tx_data_valid && tx_data_ready)//last byte sent is complete
begin
tx_cnt <= 8'd0;
tx_data_valid <= 1'b0;
state <= IDLE;///
end
else if(~tx_data_valid)
begin
tx_data_valid <= 1'b1;
end
end
WAIT:
begin
wait_cnt <= wait_cnt + 32'd1;
if(rx_data_valid == 1'b1)
begin
tx_data_valid <= 1'b1;
tx_data <= rx_data; // send uart received data
end
else if(tx_data_valid && tx_data_ready)
begin
tx_data_valid <= 1'b0;
end
else if(wait_cnt >= CLK_FRE * 1000000) // wait for 1 second
state <= IDLE;
end
default:
state <= IDLE;
endcase
end
end
reg [0:0] flag1;
reg [0:0] flag2;
reg[7:0] time1;
reg[7:0] time2;
reg[7:0] time1_1;
reg[7:0] time2_1;
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
flag1<= 1'd0; flag2<= 1'd0;
time1<= 8'd0; time2<= 8'd0;
time1_1<= 8'd0; time2_1<= 8'd0;
end
else if (key_out[0]==1'd1)
begin
if (time1 == 8'd9)
begin
time1_1<= time1_1 +8'd1; time1<= 8'd0;flag1 <= 1'd1;
end
else
begin flag1 <= 1'd1; time1 <= time1 +8'd1;end
end
else if (key_out[1]==1'd1)
begin
if (time2 == 8'd9)
begin
time2_1<= time2_1 +8'd1; time2<= 8'd0;flag2 <= 1'd1;
end
else
begin flag2 <= 1'd1; time2 <= time2 +8'd1;end
end
else if (tx_cnt == 8'd15)
begin
flag1<= 1'd0;
flag2<= 1'd0;
end
end
//combinational logic
//Send "HELLO ALINX\r\n" 一个字符占一个字节
always@(*)
begin
if(flag1||flag2)
begin
case(tx_cnt)
8'd0 : tx_str <= "N";
8'd1 : tx_str <= "O";
8'd2 : tx_str <= ".";
8'd3 : if(flag1) tx_str <= "1";else tx_str <= "2";
8'd4 : tx_str <= "+";
8'd5 : tx_str <= count5+ 8'd48;
8'd6 : tx_str <= count4+ 8'd48;
8'd7 : tx_str <= count3+ 8'd48;
8'd8 : tx_str <= count2+ 8'd48;
8'd9 : tx_str <= count1+ 8'd48;
8'd10: tx_str <= count0+ 8'd48;
8'd11: tx_str <= ".";
8'd12: if(flag1) tx_str <= time1_1+ 8'd48;else tx_str <=time2_1+ 8'd48;
8'd13: if(flag1) tx_str <= time1+ 8'd48;else tx_str <=time2+ 8'd48;
8'd14: tx_str <= "\r";
8'd15: tx_str <= "\n";
default:tx_str <= tx_str;
endcase
end
end
uart_rx#
(
.CLK_FRE(CLK_FRE),
.BAUD_RATE(115200)
) uart_rx_inst
(
.clk (clk ),
.rst_n (rst_n ),
.rx_data (rx_data ),
.rx_data_valid (rx_data_valid ),
.rx_data_ready (rx_data_ready ),
.rx_pin (uart_rx )
);
uart_tx#
(
.CLK_FRE(CLK_FRE),
.BAUD_RATE(115200)
) uart_tx_inst
(
.clk (clk ),
.rst_n (rst_n ),
.tx_data (tx_data ),
.tx_data_valid (tx_data_valid ),
.tx_data_ready (tx_data_ready ),
.tx_pin (uart_tx )
);
endmodule
//uart_rx.v
module uart_rx
#(
parameter CLK_FRE = 50, //clock frequency(Mhz)
parameter BAUD_RATE = 115200 //serial baud rate
)
(
input clk, //clock input
input rst_n, //asynchronous reset input, low active
output reg[7:0] rx_data, //received serial data
output reg rx_data_valid, //received serial data is valid
input rx_data_ready, //data receiver module ready
input rx_pin //serial data input
);
//calculates the clock cycle for baud rate
localparam CYCLE = CLK_FRE * 1000000 / BAUD_RATE;
//state machine code
localparam S_IDLE = 1;
localparam S_START = 2; //start bit
localparam S_REC_BYTE = 3; //data bits
localparam S_STOP = 4; //stop bit
localparam S_DATA = 5;
reg[2:0] state;
reg[2:0] next_state;
reg rx_d0; //delay 1 clock for rx_pin
reg rx_d1; //delay 1 clock for rx_d0
wire rx_negedge; //negedge of rx_pin
reg[7:0] rx_bits; //temporary storage of received data
reg[15:0] cycle_cnt; //baud counter
reg[2:0] bit_cnt; //bit counter
assign rx_negedge = rx_d1 && ~rx_d0;
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
rx_d0 <= 1'b0;
rx_d1 <= 1'b0;
end
else
begin
rx_d0 <= rx_pin;
rx_d1 <= rx_d0;
end
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
state <= S_IDLE;
else
state <= next_state;
end
always@(*)
begin
case(state)
S_IDLE:
if(rx_negedge)
next_state <= S_START;
else
next_state <= S_IDLE;
S_START:
if(cycle_cnt == CYCLE - 1)//one data cycle
next_state <= S_REC_BYTE;
else
next_state <= S_START;
S_REC_BYTE:
if(cycle_cnt == CYCLE - 1 && bit_cnt == 3'd7) //receive 8bit data
next_state <= S_STOP;
else
next_state <= S_REC_BYTE;
S_STOP:
if(cycle_cnt == CYCLE/2 - 1)//half bit cycle,to avoid missing the next byte receiver
next_state <= S_DATA;
else
next_state <= S_STOP;
S_DATA:
if(rx_data_ready) //data receive complete
next_state <= S_IDLE;
else
next_state <= S_DATA;
default:
next_state <= S_IDLE;
endcase
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
rx_data_valid <= 1'b0;
else if(state == S_STOP && next_state != state)
rx_data_valid <= 1'b1;
else if(state == S_DATA && rx_data_ready)
rx_data_valid <= 1'b0;
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
rx_data <= 8'd0;
else if(state == S_STOP && next_state != state)
rx_data <= rx_bits;//latch received data
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
bit_cnt <= 3'd0;
end
else if(state == S_REC_BYTE)
if(cycle_cnt == CYCLE - 1)
bit_cnt <= bit_cnt + 3'd1;
else
bit_cnt <= bit_cnt;
else
bit_cnt <= 3'd0;
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
cycle_cnt <= 16'd0;
else if((state == S_REC_BYTE && cycle_cnt == CYCLE - 1) || next_state != state)
cycle_cnt <= 16'd0;
else
cycle_cnt <= cycle_cnt + 16'd1;
end
//receive serial data bit data
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
rx_bits <= 8'd0;
else if(state == S_REC_BYTE && cycle_cnt == CYCLE/2 - 1)
rx_bits[bit_cnt] <= rx_pin;
else
rx_bits <= rx_bits;
end
endmodule
//uart_tx.v
//*******************************************************************************/
module uart_tx
#(
parameter CLK_FRE = 50, //clock frequency(Mhz)
parameter BAUD_RATE = 115200 //serial baud rate
)
(
input clk, //clock input
input rst_n, //asynchronous reset input, low active
input[7:0] tx_data, //data to send
input tx_data_valid, //data to be sent is valid
output reg tx_data_ready, //send ready
output tx_pin //serial data output
);
//calculates the clock cycle for baud rate
localparam CYCLE = CLK_FRE * 1000000 / BAUD_RATE;
//state machine code
localparam S_IDLE = 1;
localparam S_START = 2;//start bit
localparam S_SEND_BYTE = 3;//data bits
localparam S_STOP = 4;//stop bit
reg[2:0] state;
reg[2:0] next_state;
reg[15:0] cycle_cnt; //baud counter
reg[2:0] bit_cnt;//bit counter
reg[7:0] tx_data_latch; //latch data to send
reg tx_reg; //serial data output
assign tx_pin = tx_reg;
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
state <= S_IDLE;
else
state <= next_state;
end
always@(*)
begin
case(state)
S_IDLE:
if(tx_data_valid == 1'b1)
next_state <= S_START;
else
next_state <= S_IDLE;
S_START:
if(cycle_cnt == CYCLE - 1)
next_state <= S_SEND_BYTE;
else
next_state <= S_START;
S_SEND_BYTE:
if(cycle_cnt == CYCLE - 1 && bit_cnt == 3'd7)
next_state <= S_STOP;
else
next_state <= S_SEND_BYTE;
S_STOP:
if(cycle_cnt == CYCLE - 1)
next_state <= S_IDLE;
else
next_state <= S_STOP;
default:
next_state <= S_IDLE;
endcase
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
tx_data_ready <= 1'b0;
end
else if(state == S_IDLE)
if(tx_data_valid == 1'b1)
tx_data_ready <= 1'b0;
else
tx_data_ready <= 1'b1;
else if(state == S_STOP && cycle_cnt == CYCLE - 1)
tx_data_ready <= 1'b1;
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
tx_data_latch <= 8'd0;
end
else if(state == S_IDLE && tx_data_valid == 1'b1)
tx_data_latch <= tx_data;
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
bit_cnt <= 3'd0;
end
else if(state == S_SEND_BYTE)
if(cycle_cnt == CYCLE - 1)
bit_cnt <= bit_cnt + 3'd1;
else
bit_cnt <= bit_cnt;
else
bit_cnt <= 3'd0;
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
cycle_cnt <= 16'd0;
else if((state == S_SEND_BYTE && cycle_cnt == CYCLE - 1) || next_state != state)
cycle_cnt <= 16'd0;
else
cycle_cnt <= cycle_cnt + 16'd1;
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
tx_reg <= 1'b1;
else
case(state)
S_IDLE,S_STOP:
tx_reg <= 1'b1;
S_START:
tx_reg <= 1'b0;
S_SEND_BYTE:
tx_reg <= tx_data_latch[bit_cnt];
default:
tx_reg <= 1'b1;
endcase
end
endmodule