246 lines
5.9 KiB
Verilog
246 lines
5.9 KiB
Verilog
/*Copyright 2020-2021 T-Head Semiconductor Co., Ltd.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
|
|
// &ModuleBeg; @22
|
|
module uart_trans(
|
|
ctrl_trans_data_length,
|
|
ctrl_trans_parity_bit,
|
|
ctrl_trans_parity_en,
|
|
ctrl_trans_shift_data,
|
|
ctrl_trans_stop_length,
|
|
ctrl_trans_thr_vld,
|
|
rst_b,
|
|
s_out,
|
|
sys_clk,
|
|
trans_clk_en,
|
|
trans_ctrl_busy,
|
|
trans_ctrl_thr_read,
|
|
trans_ctrl_thsr_empty
|
|
);
|
|
|
|
// &Ports; @23
|
|
input [1:0] ctrl_trans_data_length;
|
|
input ctrl_trans_parity_bit;
|
|
input ctrl_trans_parity_en;
|
|
input [7:0] ctrl_trans_shift_data;
|
|
input ctrl_trans_stop_length;
|
|
input ctrl_trans_thr_vld;
|
|
input rst_b;
|
|
input sys_clk;
|
|
input trans_clk_en;
|
|
output s_out;
|
|
output trans_ctrl_busy;
|
|
output trans_ctrl_thr_read;
|
|
output trans_ctrl_thsr_empty;
|
|
|
|
// &Regs; @24
|
|
reg [2:0] conter;
|
|
reg [4:0] cur_state;
|
|
reg [4:0] next_state;
|
|
reg parity_cout;
|
|
reg s_out;
|
|
reg thsr_empty;
|
|
reg trans_ctrl_thr_read;
|
|
reg [7:0] trans_shift_reg;
|
|
|
|
// &Wires; @25
|
|
wire [1:0] ctrl_trans_data_length;
|
|
wire ctrl_trans_parity_bit;
|
|
wire ctrl_trans_parity_en;
|
|
wire [7:0] ctrl_trans_shift_data;
|
|
wire ctrl_trans_stop_length;
|
|
wire ctrl_trans_thr_vld;
|
|
wire data_over;
|
|
wire parity_bit;
|
|
wire rst_b;
|
|
wire stop_over;
|
|
wire sys_clk;
|
|
wire thsr_shift_over;
|
|
wire thsr_wen;
|
|
wire trans_clk_en;
|
|
wire trans_ctrl_busy;
|
|
wire trans_ctrl_thsr_empty;
|
|
wire trans_enable;
|
|
|
|
|
|
parameter IDLE = 5'b00001,
|
|
START = 5'b00010,
|
|
DATA = 5'b00100,
|
|
PARITY = 5'b01000,
|
|
STOP = 5'b10000;
|
|
|
|
always@(posedge sys_clk or negedge rst_b)
|
|
begin
|
|
if(!rst_b)
|
|
cur_state[4:0] <= IDLE;
|
|
else if(trans_clk_en)
|
|
cur_state[4:0] <= next_state[4:0];
|
|
end
|
|
|
|
|
|
assign trans_enable = !thsr_empty;
|
|
|
|
// &CombBeg; @44
|
|
always @( parity_bit
|
|
or stop_over
|
|
or cur_state[4:0]
|
|
or trans_enable
|
|
or ctrl_trans_parity_en
|
|
or trans_shift_reg[0]
|
|
or data_over
|
|
or thsr_wen)
|
|
begin
|
|
s_out = 1'b1;
|
|
next_state[4:0] = IDLE;
|
|
case(cur_state[4:0])
|
|
IDLE:
|
|
begin
|
|
if(trans_enable)
|
|
next_state[4:0] = START;
|
|
end
|
|
START:
|
|
begin
|
|
s_out = 1'b0;
|
|
next_state[4:0] = DATA;
|
|
end
|
|
DATA:
|
|
begin
|
|
s_out = trans_shift_reg[0];
|
|
if(data_over)
|
|
next_state[4:0] = ctrl_trans_parity_en ? PARITY : STOP;
|
|
else
|
|
next_state[4:0] = DATA;
|
|
end
|
|
PARITY:
|
|
begin
|
|
s_out = parity_bit;
|
|
next_state[4:0] = STOP;
|
|
end
|
|
STOP:
|
|
begin
|
|
s_out = 1'b1;
|
|
if(stop_over)
|
|
begin
|
|
if(thsr_wen)
|
|
next_state[4:0] = START;
|
|
else
|
|
next_state[4:0] = IDLE;
|
|
end
|
|
else
|
|
next_state[4:0] = STOP;
|
|
end
|
|
default: next_state[4:0] = IDLE;
|
|
endcase
|
|
|
|
// &CombEnd; @87
|
|
end
|
|
|
|
always@(posedge sys_clk or negedge rst_b)
|
|
begin
|
|
if(!rst_b)
|
|
conter[2:0] <= 2'b0;
|
|
else if(trans_clk_en)
|
|
begin
|
|
if(data_over || stop_over)
|
|
conter[2:0] <= 2'b0;
|
|
else if((cur_state[2]) ||(cur_state[4]))
|
|
conter[2:0] <= conter[2:0] + 1'b1;
|
|
end
|
|
end
|
|
|
|
assign data_over = (conter[2:0] == {1'b1,ctrl_trans_data_length[1:0]});
|
|
assign stop_over = (cur_state[4]) && (conter[2:0] == {2'b0,ctrl_trans_stop_length});
|
|
|
|
|
|
//==============================================================
|
|
// generate the signal to ctrl
|
|
//==============================================================
|
|
assign trans_ctrl_busy = !(cur_state[0]);
|
|
//always @(posedge trans_clk or negedge rst_b)
|
|
//begin
|
|
// if(!rst_b)
|
|
// stop_state_latch <= 1'b0;
|
|
// else
|
|
// stop_state_latch <= cur_state[4];
|
|
//end
|
|
assign thsr_shift_over = cur_state[4];
|
|
//assign trans_ctrl_shiftreg_over = thsr_shift_over;
|
|
|
|
//==============================================================
|
|
// generate the output s_out signal
|
|
//==============================================================
|
|
always@(posedge sys_clk or negedge rst_b)
|
|
begin
|
|
if( !rst_b )
|
|
trans_shift_reg[7:0] <= 8'b0;
|
|
else if(trans_clk_en)
|
|
begin
|
|
if((cur_state[2]))
|
|
trans_shift_reg[7:0] <= {1'b0,trans_shift_reg[7:1]};
|
|
else if(thsr_wen)
|
|
trans_shift_reg[7:0] <= ctrl_trans_shift_data[7:0];
|
|
end
|
|
end
|
|
|
|
always@(posedge sys_clk or negedge rst_b)
|
|
begin
|
|
if( !rst_b )
|
|
thsr_empty <= 1'b1;
|
|
else if(trans_clk_en)
|
|
begin
|
|
if( thsr_wen )
|
|
thsr_empty <= 1'b0;
|
|
else if(thsr_shift_over)
|
|
thsr_empty <= 1'b1;
|
|
end
|
|
end
|
|
|
|
assign thsr_wen = ctrl_trans_thr_vld && ( thsr_shift_over || thsr_empty);
|
|
|
|
always@(posedge sys_clk or negedge rst_b)
|
|
begin
|
|
if( !rst_b )
|
|
trans_ctrl_thr_read <= 1'b0;
|
|
else if(trans_clk_en)
|
|
begin
|
|
if( thsr_wen )
|
|
trans_ctrl_thr_read <= 1'b1;
|
|
else
|
|
trans_ctrl_thr_read <= 1'b0;
|
|
end
|
|
end
|
|
|
|
assign trans_ctrl_thsr_empty = thsr_empty;
|
|
always@(posedge sys_clk or negedge rst_b)
|
|
begin
|
|
if( !rst_b )
|
|
parity_cout <= 1'b0;
|
|
else if(trans_clk_en)
|
|
begin
|
|
if(cur_state[1])
|
|
parity_cout <= 1'b0;
|
|
else if( (cur_state[2]))
|
|
parity_cout <= parity_cout ^ trans_shift_reg[0];
|
|
end
|
|
end
|
|
|
|
assign parity_bit = ~(parity_cout ^ ctrl_trans_parity_bit);
|
|
|
|
// &ModuleEnd; @180
|
|
endmodule
|
|
|
|
|