📄 pda.v
字号:
module pda(
// 时钟输入
clk_cpld,
// 复位输入
pxa_nreset_out,// I / from CPU 复位信号
// CPU总线及控制信号
a, // I / from CPU 地址
d, // IO/ f/t CPU 数据
// CF卡信号
a_, // O / to CF 地址
d_, // IO/ f/t CF 数据
cf_bus_non, // I / from CPU
cf_ncd1, // I / from CF
cf_ncd2, // I / from CF
pxa_npcd, // O / to CPU = cf_ncd1 | cf_ncd2
cf_npiois16, // I / from CF
pxa_npiois16, // O / to CPU
cf_npwait, // I / from CF
pxa_npwait, // O / to CPU
pxa_npreg, // I / from CPU
cf_npreg, // O / to CF
pxa_npwe, // I / from CPU
cf_npwe, // O / to CF
pxa_npiowr, // I / from CPU
cf_npiowr, // O / to CF
pxa_npiord, // I / from CPU
cf_npiord, // O / to CF
pxa_npce1, // I / from CPU
cf_npce1, // O / to CF
pxa_npce2, // I / from CPU
cf_npce2, // O / to CF
pxa_npoe, // I / from CPU
cf_npoe, // O / to CF
// 串口信号
// CPU蓝牙串口
btcts, // O / to CPU
btrts, // I / from CPU
btrxd, // O / to CPU
bttxd, // I / from CPU
// CPU红外串口
rxd_2, // O / to CPU
txd_2, // I / from CPU
// 扩展条码串口
// bar_cts, // I / from BarCode
// bar_rts, // O / to BarCode
bar_rxd, // I / from BarCode
bar_txd, // O / to BarCode
// 扩展蓝牙串口
bt_cts, // I / from BlueTooth
bt_rts, // O / to BlueTooth
bt_rxd, // I / from BlueTooth
bt_txd, // O / to BlueTooth
// 扩展IC卡串口
ic_rxd, // I / from IcCard
ic_txd, // O / to IcCard
// 扩展ID卡串口
id_rxd, // I / from IdCard
id_txd, // O / to IdCard
// 扩展打印串口
prt_cts, // I / from Printer
prt_rxd, // I / from Printer
prt_txd, // O / to Printer
// IIC总线
// pxa_scl, // I / from CPU
// pxa_sda, // IO/ f/t CPU
// 键盘
key_l, // IO/ f/t KeyPad 行线
key_v, // IO/ f/t KeyPad 列线
// 电源管理输出
pm_cdma,
pm_bar,
pm_prt,
pm_id,
pm_ic,
pm_mag,
pm_bt,
pm_cf,
pm_sd,
// 其他信号
// pxa_nrd, // I / from CPU 读选通
// pxa_nwr, // I / from CPU 写选通
pxa_ncs1, // I / from CPU
pxa_ncs2, // I / from CPU
pxa_ncs4, // I / from CPU
pxa_ncs5, // I / from CPU
butt_4,
kp_dkin1,
kp_mkout4,
kp_mkout5,
pxa_gpio3,
pxa_rdy,
pxa_npskt,
);
parameter delay = 2;
parameter wait_press = 0;
parameter st0 = 0, st1 = 1, st2 = 2, st3 = 3, st4 = 4, st5 = 5, st6 = 6, st7 = 7, st8 = 8;
input clk_cpld;
input pxa_nreset_out;
input [10:0] a;
inout [15:0] d;
output [10:0] a_;
inout [15:0] d_;
input cf_bus_non;
input cf_ncd1,cf_ncd2;
output pxa_npcd;
// wire pxa_npcd;
// 由 CF_BUS_nON 选通
input cf_npiois16, cf_npwait;
output pxa_npiois16,pxa_npwait;
input pxa_npreg,pxa_npwe,pxa_npiowr,pxa_npiord,pxa_npce1,pxa_npce2,pxa_npoe;
output cf_npreg, cf_npwe, cf_npiowr, cf_npiord, cf_npce1, cf_npce2, cf_npoe;
// wire cf_npreg,pxa_npiois16,pxa_npwait,cf_npwe,cf_npiowr,cf_npiord,cf_npce1,cf_npce2,cf_npoe;
// 串口信号
// CPU蓝牙串口
output btcts; // O / to CPU
input btrts; // I / from CPU
output btrxd; // O / to CPU
input bttxd; // I / from CPU
// CPU红外串口
output rxd_2; // O / to CPU
input txd_2; // I / from CPU
// 扩展条码串口
// input bar_cts; // I / from BarCode
// output bar_rts; // O / to BarCode
input bar_rxd; // I / from BarCode
output bar_txd; // O / to BarCode
// 扩展蓝牙串口
input bt_cts; // I / from BlueTooth
output bt_rts; // O / to BlueTooth
input bt_rxd; // I / from BlueTooth
output bt_txd; // O / to BlueTooth
// 扩展IC卡串口
input ic_rxd; // I / from IcCard
output ic_txd; // O / to IcCard
// 扩展ID卡串口
input id_rxd; // I / from IdCard
output id_txd; // O / to IdCard
// 扩展打印串口
input prt_cts; // I / from Printer
input prt_rxd; // I / from Printer
output prt_txd; // O / to Printer
// IIC总线
// input pxa_scl; // I / from CPU
// inout pxa_sda; // IO/ f/t CPU
// 键盘
inout [3:0] key_l; // IO/ f/t KeyPad 行线
inout [4:0] key_v; // IO/ f/t KeyPad 列线
// 电源管理输出
output
pm_bar,
pm_bt,
pm_cdma,
pm_cf,
pm_ic,
pm_id,
pm_mag,
pm_prt,
pm_sd;
// 读写控制信号
// input pxa_nrd; // I / from CPU 读选通
// input pxa_nwr; // I / from CPU 写选通
// 其他信号
output pxa_gpio3; // GPIO_3 中断 irq
input kp_dkin1; // GPIO_11 读写 rnw
inout butt_4; // GPIO_14 数据 db0
inout pxa_ncs1; // GPIO_15 数据 db1
inout pxa_rdy; // GPIO_18 数据 db2
inout kp_mkout4; // GPIO_19 数据 db3
inout kp_mkout5; // GPIO_20 数据 db4
input pxa_ncs5; // GPIO_33 选通 ncs
input pxa_npskt; // GPIO_54 地址 ab0
input pxa_ncs2; // GPIO_78 地址 ab1
input pxa_ncs4; // GPIO_80 地址 ab2
/*********************************************************
读时序
______________
db[4:0] zz 高阻 zzzzzzzzzzz/ 数据输出 \zzzzzzzzzzzzz
\______________/
________________________
ab[2:0] xx 不关心 xxx/ 地址有效 \xxxxxxxxx
\________________________/
______________________
/ \
rnw xx 不关心 xxx/ 高电平 \xxxxxxxxx
__________________ ____________
ncs 高电平 \ 低电平 /
\______________/
写时序
________________________
db[5:0] zz 高阻 zzzzz/ 数据输入 \zzzzzzzzz
\________________________/
________________________
ab[2:0] xx 不关心 xxx/ 地址有效 \xxxxxxxxx
\________________________/
rnw xx 不关心 xxx 低电平 xxxxxxxxx
\________________________/
__________________ ____________
ncs 高电平 \ 低电平 /
\______________/
*********************************************************/
// 键盘用变量
reg irq;
reg [19:0] cnt; // 10ms定时器
reg en_cnt; // 10ms定时器使能
reg scan;
reg vertical; // 行列扫描标志 = 1 列输入 / = 0 行输入
reg [4:0] key_value [1:0];
reg [3:0] state;
// reg [3:0] key_l;
// reg [4:0] key_v;
// 串口信号
// CPU蓝牙串口
// reg btcts; // O / to CPU
// reg btrxd; // O / to CPU
// CPU红外串口
reg rxd_2; // O / to CPU
// 控制器变量
wire ncs; // 控制器片选信号/低电平有效
wire rnw; // 控制器读写信号/高为读/低为写
wire [2:0] ab; // 控制器地址总线
reg [4:0] db; // 控制器数据总线
reg [4:0] outreg [3:0]; // 4个5位输出寄存器
// 电源管理2个(只写) 0 1
// 串口选择2个(只写) 2 3
reg [4:0] inreg; // 4个5位输入寄存器
// 键盘1个(只读) 0
// 内部临时变量
wire data_buff_dir;
wire cf_data_non;
// 内部临时变量
assign #delay data_buff_dir = pxa_npiord & pxa_npoe;
assign #delay cf_data_non = cf_bus_non | ( pxa_npce1 & pxa_npce2 );
// CF接口逻辑
assign #delay a_ = a;
assign #delay d_ = ( data_buff_dir && !cf_data_non ) ? d : 16'hzzzz;
assign #delay d = ( !data_buff_dir && !cf_data_non ) ? d_ : 16'hzzzz;
assign #delay pxa_npiois16 = ( !cf_bus_non ) ? cf_npiois16 : 1'bz;
assign #delay pxa_npwait = ( !cf_bus_non ) ? cf_npwait : 1'bz;
assign #delay cf_npreg = ( !cf_bus_non ) ? pxa_npreg : 1'bz;
assign #delay cf_npwe = ( !cf_bus_non ) ? pxa_npwe : 1'bz;
assign #delay cf_npiowr = ( !cf_bus_non ) ? pxa_npiowr : 1'bz;
assign #delay cf_npiord = ( !cf_bus_non ) ? pxa_npiord : 1'bz;
assign #delay cf_npce1 = ( !cf_bus_non ) ? pxa_npce1 : 1'bz;
assign #delay cf_npce2 = ( !cf_bus_non ) ? pxa_npce2 : 1'bz;
assign #delay cf_npoe = ( !cf_bus_non ) ? pxa_npoe : 1'bz;
assign #delay pxa_npcd = cf_ncd1 | cf_ncd2;
// 控制器操作
assign ncs = pxa_ncs5;
assign rnw = kp_dkin1;
assign ab[2:0] = {pxa_ncs4,pxa_ncs2,pxa_npskt};
// 数据总线引脚
assign {kp_mkout5,kp_mkout4,pxa_rdy,pxa_ncs1,butt_4} = ( ~ncs && rnw ) ? db[4:0] : 5'bzzzzz;
always @ ( negedge ncs )
begin
if( rnw )
db[4:0] <= inreg[4:0];
else
db[4:0] <= {kp_mkout5,kp_mkout4,pxa_rdy,pxa_ncs1,butt_4};
end
always @ ( negedge clk_cpld )
begin
if( ~ pxa_nreset_out )
begin
outreg[0][4:0] <= 5'b00000;
outreg[1][4:0] <= 5'b00000;
outreg[2][4:0] <= 5'b00000;
outreg[3][4:0] <= 5'b00000;
end
else if( ~rnw && ~ncs && ( ab < 4 ))
outreg[ab][4:0] <= db[4:0];
end
// 电源管理
assign {pm_ic,pm_cf,pm_cdma,pm_bt,pm_bar} = outreg[0][4:0];
assign {pm_sd,pm_prt,pm_mag,pm_id} = outreg[1][3:0];
// 串口选择
// 打印机 / 蓝牙 / ID卡 共用蓝牙串口
assign btcts = ( outreg[2][1:0] == 2'b00 ) ? prt_cts :
(( outreg[2][1:0] == 2'b10 ) ? bt_cts : 1'bz );
/*
always @ ( negedge clk_cpld )
begin
case( outreg[2][1:0] )
2'b00: btcts <= prt_cts;
2'b10: btcts <= bt_cts;
default:btcts <= 1'bz;
endcase
end
*/
assign btrxd = ( outreg[2][1:0] == 2'b00 ) ? prt_rxd :
(( outreg[2][1:0] == 2'b01 ) ? id_rxd :
(( outreg[2][1:0] == 2'b10 ) ? bt_rxd : 1'bz ));
/*
always @ ( negedge clk_cpld )
begin
case( outreg[2][1:0] )
2'b00: btrxd <= prt_rxd;
2'b01: btrxd <= id_rxd;
2'b10: btrxd <= bt_rxd;
default:btrxd <= 1'bz;
endcase
end
*/
assign prt_txd = ( outreg[2][1:0] == 2'b00 ) ? bttxd : 1'bz;
assign id_txd = ( outreg[2][1:0] == 2'b01 ) ? bttxd : 1'bz;
assign bt_rts = ( outreg[2][1:0] == 2'b10 ) ? btrts : 1'bz;
assign bt_txd = ( outreg[2][1:0] == 2'b10 ) ? bttxd : 1'bz;
// 条码(GPS) / IC卡 共用串口2
always @ ( negedge clk_cpld )
begin
case( outreg[3][0] )
1'b0: rxd_2 <= bar_rxd;
1'b1: rxd_2 <= ic_rxd;
endcase
end
assign bar_txd = ( ~ outreg[3][0] ) ? txd_2 : 1'bz;
assign ic_txd = ( outreg[3][0] ) ? txd_2 : 1'bz;
// assign bar_rts = 1'b0;
// 键盘
// 初始化
always @ ( negedge clk_cpld )
begin
if( en_cnt )
cnt <= cnt + 1;
else
cnt <= 0;
end
assign key_l = ( vertical ) ? 4'b0000 : 4'bzzzz;
assign key_v = ( ~ vertical ) ? 5'b00000 : 5'bzzzzz;
assign pxa_gpio3 = irq;
// 状态机
always @ ( negedge clk_cpld )
begin
if(( ~ ncs && rnw ) || ~ pxa_nreset_out )
irq <= 0; // 键值被取走,则中断失效
if( ~ pxa_nreset_out )
state <= st0;
else
case( state )
st0: // 初始化
begin
en_cnt <= 0; // 停止计数器
scan <= 0; // 第一次扫描
key_value[0] <= 5'b11111; // 键值初始化
key_value[1] <= 5'b11111;
state <= st1;
end
st1: // 行输入初始化标志
begin
vertical <= 0;
state <= st2;
end
st2: // 得到行值
begin
case( key_l[3:0] )
4'b1110: begin
key_value[scan][4:3] <= 2'b00;
state <= st3;
end
4'b1101: begin
key_value[scan][4:3] <= 2'b01;
state <= st3;
end
4'b1011: begin
key_value[scan][4:3] <= 2'b10;
state <= st3;
end
4'b0111: begin
key_value[scan][4:3] <= 2'b11;
state <= st3;
end
default: state <= st0; // 多键按下或无键按下
endcase
end
st3: // 切换输入输出状态标志
begin
vertical <= 1;
state <= st4;
end
st4: // 得到列值
begin
case( key_v[4:0] )
5'b11110: begin
key_value[scan][2:0] <= 3'b000;
state <= st5;
end
5'b11101: begin
key_value[scan][2:0] <= 3'b001;
state <= st5;
end
5'b11011: begin
key_value[scan][2:0] <= 3'b010;
state <= st5;
end
5'b10111: begin
key_value[scan][2:0] <= 3'b011;
state <= st5;
end
5'b01111: begin
key_value[scan][2:0] <= 3'b100;
state <= st5;
end
default: state <= st0; // 多键按下或无键按下
endcase
end
st5: // 比较两次得到的键值是否相同
begin
if( scan == 0 ) // 完成第一次扫描
begin
scan <= 1;
en_cnt <= 1; // 启动10ms定时器
state <= st6; // 转入第二次扫描前延时去抖动
end
else if( key_value[0] == key_value[1] ) // 已经扫描两次且得到相同键值
state <= st7;
else
state <= st0; // 两次扫描得到不同键值
end
st6: // 第二次扫描前延时去抖动
begin
if( cnt[19] )
begin
en_cnt <= 0; // 停止10ms定时器
state <= st1; // 开始第二次扫描
end
end
st7: // 等待按键抬起
begin
if( key_v[4:0] == 5'b11111 )
state <= st8;
end
st8: //
begin
if( ncs || ~ rnw )
begin
inreg[4:0] <= key_value[0][4:0]; // 键值送缓冲区
irq <= 1; // 中断有效
state <= 0;
end
end
default:
state <= st0;
endcase
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -