
`timescale 1ns/ 100ps
module ps2_tx(clk,rst,tx_fifo_q,tx_fifo_empty,tx_fifo_rdreq,
tx_enable,tx_busy,txstart_mark_cnt_max,ps2_clk,ps2_data,
negedge_ps2_clk,posedge_ps2_clk,tx_ack_err,ps2_clk_out,ps2_clk_ena,ps2_data_out,ps2_data_out_ena);
input clk,rst,tx_fifo_empty,tx_enable;
inout ps2_clk,ps2_data;
output reg tx_fifo_rdreq,tx_busy;
input [15:0] txstart_mark_cnt_max;
input negedge_ps2_clk,posedge_ps2_clk;
input [7:0] tx_fifo_q;
output reg tx_ack_err;
output reg ps2_clk_out,ps2_clk_ena;
output reg ps2_data_out,ps2_data_out_ena;
reg [4:0] state;
reg [15:0] start_mark_cnt;
parameter IDLE=5'd1,WAIT_DATA=5'd2,CLR_CLK=5'd3,
WAIT_POSEDGE=5'd4,BIT0=5'd5,BIT1=5'd6,BIT2=5'd7,
BIT3=5'd8,BIT4=5'd9,BIT5=5'd10,BIT6=5'd11,BIT7=5'd12,
PARITY=5'd13,STOP=5'd14,END_TX=5'd15,WAIT_BEFORE_NEXT=5'd16,ACK=5'd17,DUMMY=5'd18;
always@(posedge clk or posedge rst) begin
if(rst) begin
state<=IDLE;
ps2_clk_ena<=1'b0;
ps2_data_out_ena<=1'b0;
ps2_clk_out<=1'b1;
ps2_data_out<=1'b1;
start_mark_cnt<=0;
tx_busy<=1'b0;tx_fifo_rdreq<=1'b0;
tx_ack_err<=1'b0;
end
else begin
case(state)
IDLE:begin
ps2_clk_ena<=1'b0;ps2_data_out_ena<=1'b0;
if(tx_enable & !tx_fifo_empty) begin state<=WAIT_DATA; tx_fifo_rdreq<=1'b1;tx_busy<=1'b1; end
else begin tx_busy<=1'b0;tx_fifo_rdreq<=1'b0;end
end
WAIT_DATA:begin tx_fifo_rdreq<=1'b0; start_mark_cnt<=0; if(tx_enable) state<=CLR_CLK;end
CLR_CLK: begin
if(!tx_enable) state<=WAIT_DATA;
else begin
ps2_clk_out<=1'b0;
start_mark_cnt<=start_mark_cnt+1;
if(start_mark_cnt>=txstart_mark_cnt_max) begin
ps2_clk_ena<=1'b0;
state<=WAIT_POSEDGE;
end
else ps2_clk_ena<=1'b1;
if (start_mark_cnt>=(txstart_mark_cnt_max-1000)) begin
ps2_data_out<=1'b0;
ps2_data_out_ena<=1'b1;
end
end
end
WAIT_POSEDGE:begin
if(negedge_ps2_clk) state<=BIT0;
end
BIT0:begin
if(negedge_ps2_clk) begin state<=BIT1;ps2_data_out<=tx_fifo_q[0];end
end
BIT1:begin if(negedge_ps2_clk) begin state<=BIT2;ps2_data_out<=tx_fifo_q[1];end end
BIT2:begin if(negedge_ps2_clk) begin state<=BIT3;ps2_data_out<=tx_fifo_q[2];end end
BIT3:begin if(negedge_ps2_clk) begin state<=BIT4;ps2_data_out<=tx_fifo_q[3];end end
BIT4:begin if(negedge_ps2_clk) begin state<=BIT5;ps2_data_out<=tx_fifo_q[4];end end
BIT5:begin if(negedge_ps2_clk) begin state<=BIT6;ps2_data_out<=tx_fifo_q[5];end end
BIT6:begin if(negedge_ps2_clk) begin state<=BIT7;ps2_data_out<=tx_fifo_q[6];end end
BIT7:begin if(negedge_ps2_clk) begin state<=PARITY;ps2_data_out<=tx_fifo_q[7];end end
PARITY:begin if(negedge_ps2_clk) begin state<=STOP;ps2_data_out<=~(^tx_fifo_q);end end
STOP: begin if(negedge_ps2_clk) begin state<=DUMMY;ps2_data_out=1'b1;ps2_data_out_ena<=1'b0;end end
DUMMY:begin if(negedge_ps2_clk)begin state<=ACK;end end
ACK:begin
start_mark_cnt<=start_mark_cnt+1;
if(posedge_ps2_clk) state<= WAIT_BEFORE_NEXT;
else if(start_mark_cnt>=txstart_mark_cnt_max)
begin
state<=END_TX;if(ps2_data!=1'b0) tx_ack_err<=1'b1;
end
end
END_TX:begin
tx_ack_err<=1'b0;
state<=WAIT_BEFORE_NEXT;
tx_busy<=1'b0;start_mark_cnt<=0;
end
WAIT_BEFORE_NEXT:begin
tx_busy<=1'b0;
start_mark_cnt<=start_mark_cnt+1;
if((start_mark_cnt>=txstart_mark_cnt_max)| !tx_enable) state<=IDLE;
end
endcase
end
end
//assign ps2_data=ps2_data_out_ena?ps2_data_out:1'bz;
//assign ps2_clk=ps2_clk_ena?ps2_clk_out:1'bz;
endmodule
这是发送模块啊 对不对啊 好复杂啊
module ps2_tx(clk,rst,tx_fifo_q,tx_fifo_empty,tx_fifo_rdreq,
tx_enable,tx_busy,txstart_mark_cnt_max,ps2_clk,ps2_data,
negedge_ps2_clk,posedge_ps2_clk,tx_ack_err,ps2_clk_out,ps2_clk_ena,ps2_data_out,ps2_data_out_ena);
input clk,rst,tx_fifo_empty,tx_enable;
inout ps2_clk,ps2_data;
output reg tx_fifo_rdreq,tx_busy;
input [15:0] txstart_mark_cnt_max;
input negedge_ps2_clk,posedge_ps2_clk;
input [7:0] tx_fifo_q;
output reg tx_ack_err;
output reg ps2_clk_out,ps2_clk_ena;
output reg ps2_data_out,ps2_data_out_ena;
reg [4:0] state;
reg [15:0] start_mark_cnt;
parameter IDLE=5'd1,WAIT_DATA=5'd2,CLR_CLK=5'd3,
WAIT_POSEDGE=5'd4,BIT0=5'd5,BIT1=5'd6,BIT2=5'd7,
BIT3=5'd8,BIT4=5'd9,BIT5=5'd10,BIT6=5'd11,BIT7=5'd12,
PARITY=5'd13,STOP=5'd14,END_TX=5'd15,WAIT_BEFORE_NEXT=5'd16,ACK=5'd17,DUMMY=5'd18;
always@(posedge clk or posedge rst) begin
if(rst) begin
state<=IDLE;
ps2_clk_ena<=1'b0;
ps2_data_out_ena<=1'b0;
ps2_clk_out<=1'b1;
ps2_data_out<=1'b1;
start_mark_cnt<=0;
tx_busy<=1'b0;tx_fifo_rdreq<=1'b0;
tx_ack_err<=1'b0;
end
else begin
case(state)
IDLE:begin
ps2_clk_ena<=1'b0;ps2_data_out_ena<=1'b0;
if(tx_enable & !tx_fifo_empty) begin state<=WAIT_DATA; tx_fifo_rdreq<=1'b1;tx_busy<=1'b1; end
else begin tx_busy<=1'b0;tx_fifo_rdreq<=1'b0;end
end
WAIT_DATA:begin tx_fifo_rdreq<=1'b0; start_mark_cnt<=0; if(tx_enable) state<=CLR_CLK;end
CLR_CLK: begin
if(!tx_enable) state<=WAIT_DATA;
else begin
ps2_clk_out<=1'b0;
start_mark_cnt<=start_mark_cnt+1;
if(start_mark_cnt>=txstart_mark_cnt_max) begin
ps2_clk_ena<=1'b0;
state<=WAIT_POSEDGE;
end
else ps2_clk_ena<=1'b1;
if (start_mark_cnt>=(txstart_mark_cnt_max-1000)) begin
ps2_data_out<=1'b0;
ps2_data_out_ena<=1'b1;
end
end
end
WAIT_POSEDGE:begin
if(negedge_ps2_clk) state<=BIT0;
end
BIT0:begin
if(negedge_ps2_clk) begin state<=BIT1;ps2_data_out<=tx_fifo_q[0];end
end
BIT1:begin if(negedge_ps2_clk) begin state<=BIT2;ps2_data_out<=tx_fifo_q[1];end end
BIT2:begin if(negedge_ps2_clk) begin state<=BIT3;ps2_data_out<=tx_fifo_q[2];end end
BIT3:begin if(negedge_ps2_clk) begin state<=BIT4;ps2_data_out<=tx_fifo_q[3];end end
BIT4:begin if(negedge_ps2_clk) begin state<=BIT5;ps2_data_out<=tx_fifo_q[4];end end
BIT5:begin if(negedge_ps2_clk) begin state<=BIT6;ps2_data_out<=tx_fifo_q[5];end end
BIT6:begin if(negedge_ps2_clk) begin state<=BIT7;ps2_data_out<=tx_fifo_q[6];end end
BIT7:begin if(negedge_ps2_clk) begin state<=PARITY;ps2_data_out<=tx_fifo_q[7];end end
PARITY:begin if(negedge_ps2_clk) begin state<=STOP;ps2_data_out<=~(^tx_fifo_q);end end
STOP: begin if(negedge_ps2_clk) begin state<=DUMMY;ps2_data_out=1'b1;ps2_data_out_ena<=1'b0;end end
DUMMY:begin if(negedge_ps2_clk)begin state<=ACK;end end
ACK:begin
start_mark_cnt<=start_mark_cnt+1;
if(posedge_ps2_clk) state<= WAIT_BEFORE_NEXT;
else if(start_mark_cnt>=txstart_mark_cnt_max)
begin
state<=END_TX;if(ps2_data!=1'b0) tx_ack_err<=1'b1;
end
end
END_TX:begin
tx_ack_err<=1'b0;
state<=WAIT_BEFORE_NEXT;
tx_busy<=1'b0;start_mark_cnt<=0;
end
WAIT_BEFORE_NEXT:begin
tx_busy<=1'b0;
start_mark_cnt<=start_mark_cnt+1;
if((start_mark_cnt>=txstart_mark_cnt_max)| !tx_enable) state<=IDLE;
end
endcase
end
end
//assign ps2_data=ps2_data_out_ena?ps2_data_out:1'bz;
//assign ps2_clk=ps2_clk_ena?ps2_clk_out:1'bz;
endmodule
这是发送模块啊 对不对啊 好复杂啊
