📄 ps2_sie.v
字号:
else rx_ctl_ns <= RX_CTL_IDLE;
end
//IDLE -> STARTCNT reset rx_bit_count and q-reg
//STARTCNT: (an intermediate state) start counting and register rx data
RX_CTL_STARTCNT: rx_ctl_ns <= RX_CTL_GETB1;
RX_CTL_GETB1: begin
if (rx_bit_count == 11) rx_ctl_ns <= RX_CTL_CHECKB1;
else rx_ctl_ns <= RX_CTL_GETB1;
end
RX_CTL_CHECKB1: begin
if (bit_err1) rx_ctl_ns <= RX_CTL_ERR1;
else rx_ctl_ns <= RX_CTL_USEB1;
end
RX_CTL_ERR1: rx_ctl_ns <= RX_CTL_IDLE;
RX_CTL_USEB1: rx_ctl_ns <= RX_CTL_IDLE;
default : rx_ctl_ns <= RX_CTL_IDLE;
endcase
end
//------------------
//RX shift register & bit counter
//------------------
//IDLE->RSTCNT: clear q-reg, clear rx_bit_count
//delicate rx_bit_counter
always @(posedge Clk)
begin
if (Rst || rx_sta_idle) begin
q <= 0;
rx_bit_count <= 0;
end
else if ( (clk_fall && ~ rx_sta_idle) || rx_sta_startcnt ) begin
q <= {rx_2,q[0:9]};
rx_bit_count <= rx_bit_count + 1;
end
else if ( bit_wdt_done || (clk_fall && rx_sta_idle )) begin
q <= 0;
rx_bit_count <= 0;
end
end
//-----------------------------------
//RX_CTL_CHECKB1
//-----------------------------------
//Check start/stop/parity bit
//Notice the bit ordering in phsucal SReg is [0:10]
// b0 b1 b2~b9 b10 ;
// STOP PARITY DATA START
assign bit_err1 = ~ ( (q[10] == 0) // start
&& (q[0] == 1) // stop
&& (q[1] == ~^q[2:9]) // odd parity bit
);
//wire start_bit = q[10];
//wire stop_bit = q[0];
//wire odd_parity= q[1];
//wire xnor_data = ~^q[2:9];
//-------------
//RX_CTL_ERR1
//-------------
assign rx_err_set = rx_sta_err1;
//-------------
//RX_CTL_USEB1
//-------------
assign rx_data = q[2:9];
assign rx_full_set = rx_sta_useb1;
//check if previous data has been processed by host software,
//if not, then the new upcomming rx data will cause overflow.
assign rx_ovf_set = rx_sta_useb1 & rx_full_sta_dly;
always @ (posedge Clk)
begin
if (Rst)
rx_full_sta_dly <= 0;
else rx_full_sta_dly <= rx_full_sta;
end
//-----------------------------------------------------------------
//This statemachine controls Transmission flow (TX_CTL)
//-----------------------------------------------------------------
always @(posedge Clk)
begin
if (Rst) tx_ctl_cs <= TX_CTL_IDLE;
else tx_ctl_cs <= tx_ctl_ns ;
end
always @(posedge Clk)
begin
if (Rst) Txpd <= 0;
else if ((clk_fall && tx_busy ) || tx_sta_datapd ) Txpd <= txpd_i ;
end
always @(tx_ctl_cs or
tx_full_sta or
rx_bit_count or
rts_cnt_done or
clk_fall or
tx_data or clk_rise)
begin
case (tx_ctl_cs )
TX_CTL_IDLE : begin
txpd_i <= 1'b0;
if (tx_full_sta) tx_ctl_ns <= TX_CTL_WAIT ;
else tx_ctl_ns <= TX_CTL_IDLE ;
end
TX_CTL_WAIT : begin
txpd_i <= 1'b0;
if ( ~(rx_bit_count == 10) && ~(rx_bit_count == 11) )
tx_ctl_ns <= TX_CTL_CLKPD;
else tx_ctl_ns <= TX_CTL_WAIT;
end
TX_CTL_CLKPD : begin
txpd_i <= 1'b0;
if ( rts_cnt_done ) tx_ctl_ns <= TX_CTL_DATAPD;
else tx_ctl_ns <= TX_CTL_CLKPD;
end
TX_CTL_DATAPD : begin
txpd_i <= 1'b1; //Start bit
tx_ctl_ns <= TX_CTL_SND7;
end
TX_CTL_SND7 : begin
txpd_i <= ~tx_data[7];
if ( clk_fall ) begin
tx_ctl_ns <= TX_CTL_SND6;
end
else begin
tx_ctl_ns <= TX_CTL_SND7;
end
end
TX_CTL_SND6 : begin
txpd_i <= ~tx_data[6];
if ( clk_fall ) begin
tx_ctl_ns <= TX_CTL_SND5;
end
else begin
tx_ctl_ns <= TX_CTL_SND6;
end
end
TX_CTL_SND5 : begin
txpd_i <= ~tx_data[5];
if ( clk_fall )begin
tx_ctl_ns <= TX_CTL_SND4;
end
else begin
tx_ctl_ns <= TX_CTL_SND5;
end
end
TX_CTL_SND4 : begin
txpd_i <= ~tx_data[4];
if ( clk_fall )begin
tx_ctl_ns <= TX_CTL_SND3;
end
else begin
tx_ctl_ns <= TX_CTL_SND4;
end
end
TX_CTL_SND3 : begin
txpd_i <= ~tx_data[3];
if ( clk_fall )begin
tx_ctl_ns <= TX_CTL_SND2;
end
else begin
tx_ctl_ns <= TX_CTL_SND3;
end
end
TX_CTL_SND2 : begin
txpd_i <= ~tx_data[2];
if ( clk_fall )begin
tx_ctl_ns <= TX_CTL_SND1;
end
else begin
tx_ctl_ns <= TX_CTL_SND2;
end
end
TX_CTL_SND1 : begin
txpd_i <= ~tx_data[1];
if ( clk_fall )begin
tx_ctl_ns <= TX_CTL_SND0;
end
else begin
tx_ctl_ns <= TX_CTL_SND1;
end
end
TX_CTL_SND0 : begin
txpd_i <= ~tx_data[0];
if ( clk_fall )begin
tx_ctl_ns <= TX_CTL_PRTY ;
end
else begin
tx_ctl_ns <= TX_CTL_SND0;
end
end
TX_CTL_PRTY : begin
txpd_i <= ^tx_data[0:7];
if ( clk_fall )begin
tx_ctl_ns <= TX_CTL_STOP ;
end
else begin
tx_ctl_ns <= TX_CTL_PRTY;
end
end
TX_CTL_STOP : begin
txpd_i <= 1'b0;
if ( clk_fall )begin
tx_ctl_ns <= TX_CTL_WAITFEDGE ;
end
else begin
tx_ctl_ns <= TX_CTL_STOP;
end
end
TX_CTL_WAITFEDGE : begin
txpd_i <= 1'b0;
if ( clk_fall )
tx_ctl_ns <= TX_CTL_CHKACK;
else tx_ctl_ns <= TX_CTL_WAITFEDGE;
end
TX_CTL_CHKACK: begin txpd_i <= 1'b0;
if (clk_rise )
tx_ctl_ns <= TX_CTL_IDLE;
else tx_ctl_ns <= TX_CTL_CHKACK;
end
default: begin txpd_i <= 1'b0;
tx_ctl_ns <= TX_CTL_IDLE;
end
endcase
end
//-------------
//TX_CTL_CLKPD & TX_CTL_DATAPD
//-------------
//register this to avoid glitch
always @ (posedge Clk)
begin
if (Rst)
Clkpd <= 0;
else Clkpd <= tx_sta_clkpd || tx_sta_datapd;
end
//------------------
//TX_CTL_CHKACK
//------------------
//Delay tx status update.
//tx status cannot be updated until state TX_CTL_CHKACK has completed
always @(posedge Clk)
begin
if (Rst || tx_sta_idle)
begin
tx_ack_set_temp <= 1'b0;
tx_noack_set_temp <= 1'b0;
tx_full_clr_temp <= 1'b0;
end
else if (tx_sta_waitfedge && clk_fall)
begin
tx_ack_set_temp <= (~ rx_2);
tx_noack_set_temp <= (rx_2);
tx_full_clr_temp <= 1'b1;
end
end
//assign tx_ack_set = tx_sta_chkack & (~ rx_2);
//assign tx_noack_set = tx_sta_chkack & (rx_2);
//assign tx_full_clr = tx_sta_chkack;
assign tx_ack_set = ( tx_sta_chkack &&tx_sta_idle_next)? tx_ack_set_temp :1'b0;
assign tx_noack_set = ( tx_sta_chkack &&tx_sta_idle_next)? tx_noack_set_temp :1'b0;
assign tx_full_clr = ( tx_sta_chkack &&tx_sta_idle_next)? tx_full_clr_temp :1'b0;
//----------------------------------------
// Misc counter sections
//----------------------------------------
//------------
// Debounce counter. DBC reset at clock edges
//------------
always @ (posedge Clk)
begin
if (Rst || clk_fall || clk_rise)
dbc_counter <= 0;
else dbc_counter <= dbc_counter + 1;
end
assign dbc_done = (dbc_counter == DBC_TMR_VALUE -1);
//------------
// WatchDog timer. WTD reset at clock edges
//------------
always @ (posedge Clk)
begin
if (Rst || clk_fall|| clk_rise || (rx_sta_idle && tx_sta_idle ))
bit_wdt_counter <= 0;
else bit_wdt_counter <= bit_wdt_counter + 1;
end
assign bit_wdt_done = (bit_wdt_counter == BIT_WDT_TMR_VALUE -1);
assign wdt_tout_set = bit_wdt_done ;
//------------
// Request-to-Send timer.
//------------
always @ (posedge Clk)
begin
if (Rst || (tx_sta_clkpd_next && tx_sta_wait) )
rts_counter <= 0;
else rts_counter <= rts_counter + 1;
end
assign rts_cnt_done = (rts_counter == REQ_SND_VALUE -1);
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -