⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pda.v

📁 PXA255外围扩展功能
💻 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 + -