//0x4000:一般外设,0x4000,A13:0,A12:0
//0x2000:SL811,0x2000,A13:1,A12:0
//0x5000:RTL8019,0x5000,A13:0,A12:1
/*下面是对外设的各个地址进行了宏定义*/
//Read Add
`define INT1Add 6'h01
`define NMIAdd 6'h02
`define R_FIFO_Sta 6'h03
`define R_PA_Sta 6'h04
`define R_KEY 6'h08
`define USB_RW 6'h0d
`define R_IO_IN_L 6'h0e
`define R_IO_IN_H 6'h0f
//Write Add
`define BUZZERAdd 6'h00
`define LedAdd 6'h01
`define EAdd 6'h02
`define RSAdd 6'h03
`define LCDDataAdd 6'h04
`define SPI_CSAdd 6'h05
`define SIAdd 6'h06
`define PATENDAdd 6'h07
`define W_IO_OUT_L 6'h0e
`define W_IO_OUT_H 6'h0f
/*模块变量定义*/
module cpld_QQ2812(DSP_Add,DSP_Data,WR,RD,CS1,BUZZER,Key,LED,E,RS,LCD_Data,
PA0,PA1,SLOE,PATEND,SLCS,IFCLK,CLKOUT,SLRD,SLWR,FIFO_PROG,FIFO_FULL,FIFO_EMPTY,
SPI_CS,ACICS,SIDIN,SICLK,IN,OUT,INT1,NMI,EXINT,NMI1,NMI2,TXB,TXB1,RXB,CANRX,CANTX,CANRX_1,CANTX_1);
/*CPLD输入信号的定义*/
input [5:0] DSP_Add; //DSP对CPLD的地址定义
input WR,RD,CS1; //读写和CPLD片选定义
input [7:0] Key; //8个按键定义
input PA0,PA1;
input IFCLK,CLKOUT,FIFO_PROG,FIFO_FULL,FIFO_EMPTY; //USB控制信号定义
input [15:0] IN; //外扩16个IO输入定义
input [4:0] EXINT; //5个外中断定义
input NMI1,NMI2; //两个不可屏蔽中断定义
input RXB,TXB; //485信号发送接收定义
input CANTX,CANRX_1;
/*CPLD输出信号的定义*/
output CANRX,CANTX_1;
output TXB1; //485控制信号输出
output INT1,NMI; //外部可屏蔽中断控制1和不可屏蔽中断输出控制信号
output [15:0] OUT; //外扩16个IO口输出定义
output ACICS,SIDIN,SICLK; //音频片选及数据时钟全部定义为输出
output SLOE,PATEND,SLCS;
output SLRD,SLWR;
output [7:0] LED; //8位LED等定义输出
output BUZZER; //蜂鸣器控制定义输出
output E,RS; //1602控制信号的定义
output [7:0] LCD_Data; //1602和12864LCD的8位数据定义为输出
output SPI_CS; //SPI片选定义为输出
inout [7:0]DSP_Data; //DSP与CPLD之间的数据线定义为输入输出
/*变量寄存器的定义*/
reg CANRX_reg,CANTX_1_reg;
reg [7:0] DSP_Data_reg;
reg BUZZER_reg;
reg [7:0] LED_reg;
reg [7:0] LED_reg_temp;
reg [7:0] LCD_Data_reg;
reg E_reg,RS_reg;
reg [7:0] Key_reg;
reg PATEND_reg;
reg SPI_CS_reg;
reg ACICS_reg,SIDIN_reg,SICLK_reg;
reg [15:0] OUT_reg;
reg INT1_reg;
reg NMI_reg;
reg [4:0] EXINT_reg;
reg NMI1_reg,NMI2_reg;
//*循环执行判断按键与CAN发送接收的变化*/
always
begin
Key_reg=Key;
CANRX_reg=CANRX_1;
CANTX_1_reg=CANTX;
LED_reg=LED_reg_temp& Key_reg;
end
/*上边沿写信号发生,主要是将DSP的数据送到CPLD定义的各自的的寄存器中,也就是通过识别不同的地址来把数据写入各自寄存器中*/
always @ ( posedge WR)
begin
if(CS1==1'b0) //判断CPLD是否被片选
begin
case (DSP_Add) //这里选用了CASE语句来做多分选择
`BUZZERAdd: //蜂鸣器地址
begin
BUZZER_reg=DSP_Data[0]; //将DSP送来的第0位数据寄存在CPLD定义的蜂鸣器寄存器中
end
`LedAdd: //LED灯地址
begin
LED_reg_temp=DSP_Data ; //将DSP送来的数据与按键寄存器值相与得一变量
end
`EAdd: //1602使能地址
begin
E_reg=DSP_Data[0]; //DSP的第0位数据送入1602使能控制端
end
`RSAdd: // 1602片选控制端地址
begin
RS_reg=DSP_Data[0]; //DSP的第0位数据送入1602使能控制端
end
`LCDDataAdd: //1602和12864LCD数据线地址
begin
LCD_Data_reg=DSP_Data; //DSP数据送入CPLD中的数据寄存器中
end
`SPI_CSAdd: //SPI片选地址
begin
SPI_CS_reg=DSP_Data[0]; //DSP的第0位数据送如SPI片选寄存器中
end
`SIAdd: //音频信号地址
begin
ACICS_reg=DSP_Data[0]; //片选数据写入
SIDIN_reg=DSP_Data[1]; //串行数据输入
SICLK_reg=DSP_Data[2]; //串行时钟输入
end
`W_IO_OUT_L: //写IO口低位字节输出
begin
OUT_reg[7:0]=DSP_Data; //DSP向低位输出寄存器中送数据
end
`W_IO_OUT_H: //写IO口高位字节输出
begin
OUT_reg[15:8]=DSP_Data; //DSP向高位输出寄存器中送数据
end
`PATENDAdd:
begin
PATEND_reg=DSP_Data[0];
end
endcase
end
end
/*下降沿来读数据,这里主要是从CPLD中读数据到DSP中,与上面的DSP往CPLD中写数据正好相反*/
always @ ( negedge RD)
begin
if(CS1==1'b0) //CPLD被片选
begin
case (DSP_Add)
`R_IO_IN_L: //读IO口输入的低字节数据地址
begin
DSP_Data_reg=IN[7:0]; //将从外部输入的低8位数据送入CPLD中的DSP的数据寄存器
end
`R_IO_IN_H: //读IO口输入的高字节数据地址
begin
DSP_Data_reg=IN[15:8]; //将从外部输入的高8位数据送入CPLD中的DSP的数据寄存器
end
`INT1Add: //读外部可屏蔽中断1地址
begin
DSP_Data_reg[4:0]=EXINT_reg; //将5个外部中断数据送入CPLD中的DSP数据寄存器中
end
`NMIAdd: //读外部不可屏蔽中断地址
begin
DSP_Data_reg[1:0]={NMI2_reg,NMI1_reg};
end
`R_FIFO_Sta: //读USB的FIFO的状态地址
begin
DSP_Data_reg[2:0]={FIFO_PROG,FIFO_FULL,FIFO_EMPTY}; //将读到的3个不同的状态值放入CPLD的DSP数据寄存器中
end
`R_PA_Sta: //读USB的PA口的状态地址
begin
DSP_Data_reg[1:0]={PA1,PA0};
end
`R_KEY:
begin
DSP_Data_reg=Key_reg;
end
endcase
end
end
always @ (EXINT) //循环判断EXINT的变换情况
begin
if((EXINT & 5'b11111) != (5'b11111)) //判断CPLD外扩的5个中断是否有低电平产生(低电平说明中断已产生)
begin
EXINT_reg=EXINT; //把产生中断后的数据送入CPLD的外中断寄存器中
INT1_reg=0; //给DSP中断1付值,说明有中断发生
end
else
begin
INT1_reg=1; //未产生中断,不对DSP做变化
end
end
always @ (NMI1 or NMI2) //循环判断对NMI1和NMI2的变换情况
begin
if((NMI2==0) || (NMI1==0) ) //判断是否为0,即产生中断
begin
NMI1_reg=NMI1;
NMI2_reg=NMI2;
NMI_reg=0; //产生中断,并将中断信号送给DSP
end
else
begin
NMI_reg=1; //未产生中断,对DSP没有任何影响
end
end
assign SLCS=(CS1==1'b0 && DSP_Add==6'h0d)?0:1; //片选Slave FIFO
assign SLOE=(CS1==1'b0 && DSP_Add==6'h0d && RD==1'b0)?0:1; //输出使能Slave FIFO
assign SLWR=(CS1==1'b0 && DSP_Add==6'h0d && WR==1'b0)?0:1; //FIFO写使能
assign SLRD=(CS1==1'b0 && DSP_Add==6'h0d && RD==1'b0)?0:1; //FIFO读使能
assign PATEND=PATEND_reg; //FIFO包结束
assign BUZZER=BUZZER_reg; //前面定义的CPLD蜂鸣器寄存器中的值送过CPLD蜂鸣器输出管脚变量BUZZER
assign LED=LED_reg;
assign E=E_reg;
assign RS=RS_reg;
assign LCD_Data=LCD_Data_reg;
assign SPI_CS=SPI_CS_reg;
assign ACICS=ACICS_reg;
assign SIDIN=SIDIN_reg;
assign SICLK=SICLK_reg;
assign OUT=OUT_reg;
assign INT1=INT1_reg;
assign NMI=NMI_reg;
assign TXB1=~TXB;
assign CANRX=CANRX_reg;
assign CANTX_1=CANTX_1_reg;
assign DSP_Data = (CS1 == 1'b0 && RD == 1'b0 && DSP_Add[5]=='b0 && DSP_Add[4]==1'b0) ? DSP_Data_reg:8'hz;
endmodule