?? control_logic.v
字號:
/*
//*************************************************************************
// Project Name: 8255A的功能設計和分析
// Module Name : Control_Logic
// Author: 張文濤
// Created: 2006-10-25
// Modified: 2006-10-29
// Revision: 3.0
//
//*************************************************************************
// 需要注意的地方:1.Port_En在等于0時允許輸入,等于1時允許輸出;
// 2.Port_Ld在等于0時有效,允許數據IO;
// 3.PortA_IO=0時為輸入,=1時為輸出,與控制字中相反;
//*************************************************************************
*/
module Control_Logic(//input
reset,
nRD,
nWR,
A,
Din,
nSTBA,
nSTBB,
nACKA,
nACKB,
//output
Data_En,
PortA_IO_En,
PortB_IO_En,
PortC_IO_En,
PortA_In_Ld,
PortB_In_Ld,
PortA_Out_Ld,
PortB_Out_Ld,
PortC_Out_Ld,
Control_Data,
Dout_Select
);
//-----端口聲明-----
input reset; //復位信號,高電平有效;
input nRD; //讀信號,低電平有效;
input nWR; //寫信號,低電平有效;
input[1:0] A; //地址信號;
input[7:0] Din; //數據口,與CPU通信;
input nSTBA; //A口選通信號,由外設輸入;
input nSTBB; //B口選通信號,由外設輸入;
input nACKA; //A口應答信號,由外設輸入;
input nACKB; //B口應答信號,由外設輸入;
output Data_En; //Data總線選擇信號;
output PortA_IO_En; //A口總線選擇信號;
output PortB_IO_En; //B口總線選擇信號;
output[7:0] PortC_IO_En; //C口總線選擇信號;
output PortA_In_Ld; //A口輸入允許信號;
output PortB_In_Ld; //B口輸入允許信號;
output PortA_Out_Ld; //A口輸出允許信號;
output PortB_Out_Ld; //B口輸出允許信號;
output[7:0] PortC_Out_Ld; //C口輸出允許信號;
output[6:0] Control_Data; //給PC_IO的控制信號;
output[1:0] Dout_Select; //給Dout_Mux的選擇信號;
//-----內部寄存器聲明-----
reg Data_En;
reg PortA_IO_En;
reg PortB_IO_En;
reg[7:0] PortC_IO_En;
reg PortA_In_Ld;
reg PortB_In_Ld;
reg PortA_Out_Ld;
reg PortB_Out_Ld;
reg[7:0] PortC_Out_Ld;
reg[6:0] Control_Data;
reg[1:0] Dout_Select;
reg Control_Flag; //方式選擇控制字標志位;
reg[1:0] ModeA; //A口方式;
reg PortA_IO; //A口I/O;
reg PortC_Up_IO; //C口高四位I/O;
reg ModeB; //B口方式
reg PortB_IO; //B口I/O;
reg PortC_Low_IO; //C口低四位I/O;
reg[2:0] BitSelect; //置位/復位位選擇;
reg PortC_RS; //置位/復位;
////////////////////////////控制字寄存器賦值/////////////////////////////
//-----控制字標志位-----
always @ (reset or A or nWR or Din)
if(reset)
Control_Flag = 1'b0;
else if(A==2'b11 && Din[7]==1'b0)
Control_Flag = 1'b0;
else
Control_Flag = 1'b1;
//-----A口方向-----
always @ (reset or A or nWR or Din)
if(reset)
PortA_IO = 1'b0;
else if(A==2'b11 && nWR==1'b0 && Din[7]==1'b1 && ModeA!=2'b10)
PortA_IO = ~Din[4];
else if(ModeA==2'b10)
begin
if(nSTBA==1'b0)
PortA_IO = 1'b0;
else if(nACKA==1'b0)
PortA_IO = 1'b1;
else
PortA_IO = PortA_IO;
end
else
PortA_IO = PortA_IO;
//-----方式選擇控制字-----
always @ (reset or A or nWR or Din)
if(reset)
begin
ModeA = 2'b00; //復位,寄存器全部清零;
PortC_Up_IO = 1'b0;
ModeB = 1'b0;
PortB_IO =1'b0;
PortC_Low_IO =1'b0;
end
else if(A==2'b11 && nWR==1'b0 && Din[7]==1'b1) //方式選擇控制字;
begin
PortC_Up_IO = ~Din[3];
ModeB = Din[2];
PortB_IO = ~Din[1];
PortC_Low_IO = ~Din[0];
ModeA = (Din[6])?2'b10:{Din[6:5]};
end
else //其它情況鎖存原值;
begin
ModeA = ModeA;
PortC_Up_IO = PortC_Up_IO;
ModeB = ModeB;
PortB_IO = PortB_IO;
PortC_Low_IO = PortC_Low_IO;
end
//-----置位/復位控制字-----
always @ (reset or A or nWR or Din)
if(reset)
begin
BitSelect = 3'b000;
PortC_RS = 1'b0;
end
else if(A==2'b11 && nWR==1'b0 && Din[7]==1'b0)
begin
BitSelect = Din[3:1];
PortC_RS = Din[0];
end
else
begin
BitSelect = 3'b000;
PortC_RS = 1'b0;
end
////////////////////////////輸入輸出選擇Port_En/////////////////////////////////
//-----Data_En-----
always @ (reset or nRD or nWR)
if(reset)
Data_En = 1'b0;
else if(!nWR)
Data_En = 1'b0;
else if(!nRD)
Data_En = 1'b1;
else
Data_En = 1'b0;
//-----PortA_IO_En-----
always @ (reset or ModeA or PortA_IO or nACKA)
if(reset) //復位清0;
PortA_IO_En = 1'b0;
else //由輸入輸出方向決定;
PortA_IO_En = PortA_IO;
//-----PortB_IO_En-----
always @ (reset or ModeB or PortB_IO)
if(reset) //復位清0;
PortB_IO_En = 1'b0;
else //由輸入輸出方向決定;
PortB_IO_En = PortB_IO;
//-----PortC_IO_En-----
always @ (reset or ModeB or PortC_Low_IO)
if(reset) //低三位,由B口決定;
PortC_IO_En[2:0] = 3'b000;
else if(ModeB==1'b1) //B口方式1;
PortC_IO_En[2:0] = {1'b0,1'b1,1'b1};
else //B口方式0;
PortC_IO_En[2:0] = {3{PortC_Low_IO}};
always @ (reset or ModeA or PortC_Up_IO or PortC_Low_IO or PortA_IO)
if(reset) //高5位,由A口決定;
PortC_IO_En[7:3] = 5'b00000;
else if(ModeA==2'b10) //A口方式2;
PortC_IO_En[7:3] = 5'b10101;
else if(ModeA==2'b01) //A口方式1,與方向有關;
begin
if(PortA_IO==1'b0) //A口方式1輸入;
PortC_IO_En[7:3] = {{2{PortC_Up_IO}},1'b1,1'b0,1'b1};
else //A口方式2輸入;
PortC_IO_En[7:3] = {1'b1,1'b0,{2{PortC_Up_IO}},1'b1};
end
else //A口方式0;
PortC_IO_En[7:3] = {{4{PortC_Up_IO}},PortC_Low_IO};
////////////////////////////鎖存允許Port_Ld///////////////////////////
//-----PortA_In_Ld-----
always @ (reset or A or PortA_IO or nSTBA)
if(reset)
PortA_In_Ld = 1'b0; //復位清0;
else if(ModeA==2'b00 && A==2'b00 && PortA_IO==1'b0) //A口選中,數據輸入,方式0;
PortA_In_Ld = 1'b0;
else if(ModeA!=2'b00 && A==2'b00 && PortA_IO==1'b0 && nSTBA==1'b0)
PortA_In_Ld = 1'b0; //A口選中,數據輸入,方式1/2,應答信號有效;
else
PortA_In_Ld = 1'b1; //其它情況;
//-----PortB_In_Ld-----
always @ (reset or A or PortB_IO or nSTBB)
if(reset) //復位清0;
PortB_In_Ld = 1'b0;
else if(ModeA==2'b00 && A==2'b01 && PortB_IO==1'b0) //B口選中,數據輸入;
PortB_In_Ld = 1'b0;
else if(ModeA!=2'b00 && A==2'b01 && PortB_IO==1'b0 && nSTBB==1'b0)
PortB_In_Ld = 1'b0; //B口選中,數據輸入,方式1/2,應答信號有效;
else //其它情況;
PortB_In_Ld = 1'b1;
//-----PortA_Out_Ld-----
always @ (reset or A or PortA_IO)
if(reset) //復位清0;
PortA_Out_Ld = 1'b0;
else if(A==2'b00 && PortA_IO==1'b1) //A口選中,數據輸出;
PortA_Out_Ld = 1'b0;
else //其它情況;
PortA_Out_Ld = 1'b1;
//-----PortB_Out_Ld-----
always @ (reset or A or PortB_IO)
if(reset) //復位清0;
PortB_Out_Ld = 1'b0;
else if(A==2'b01 && PortB_IO==1'b1) //B口選中,數據輸出;
PortB_Out_Ld = 1'b0;
else //其它情況;
PortB_Out_Ld = 1'b1;
//-----PortC_Out_Ld-----
always @ (reset or Control_Flag or ModeA or ModeB or Din[3:0] or PortA_IO)
if(reset)
PortC_Out_Ld = 8'b00000_000;
else if(Control_Flag==0) //置位復位選擇控制字,相應位為0;
begin
case(Din[3:1])
3'b000: PortC_Out_Ld = 8'b11111110 ;
3'b001: PortC_Out_Ld = 8'b11111101 ;
3'b010: PortC_Out_Ld = 8'b11111011 ;
3'b011: PortC_Out_Ld = 8'b11110111 ;
3'b100: PortC_Out_Ld = 8'b11101111 ;
3'b101: PortC_Out_Ld = 8'b11011111 ;
3'b110: PortC_Out_Ld = 8'b10111111 ;
3'b111: PortC_Out_Ld = 8'b01111111 ;
default: PortC_Out_Ld = 8'b11111111 ;
endcase
end
else //方式選擇控制字,作數據IO的相應位為0;
if(ModeA==2'b00 && ModeB==1'b0) //A口方式0,B口方式0;
PortC_Out_Ld = 8'b00000000;
else if(ModeA==2'b00 && ModeB==1'b1) //A口方式0,B口方式1;
PortC_Out_Ld = 8'b00000111;
else if(ModeA==2'b01 && PortA_IO==1'b0 && ModeB==1'b0)//A口方式1輸入,B口方式0;
PortC_Out_Ld = 8'b00111000;
else if(ModeA==2'b01 && PortA_IO==1'b0 && ModeB==1'b1)//A口方式1輸入,B口方式1;
PortC_Out_Ld = 8'b00111111;
else if(ModeA==2'b01 && PortA_IO==1'b1 && ModeB==1'b0)//A口方式1輸出,B口方式0;
PortC_Out_Ld = 8'b11001000;
else if(ModeA==2'b01 && PortA_IO==1'b1 && ModeB==1'b1)//A口方式1輸出,B口方式1;
PortC_Out_Ld = 8'b11001111;
else if(ModeA==2'b10 && ModeB==1'b0) //A口方式2,B口方式0;
PortC_Out_Ld = 8'b11111000;
else if(ModeA==2'b10 && ModeB==1'b1) //A口方式2,B口方式1;
PortC_Out_Ld = 8'b11111111;
else //其它情況;
PortC_Out_Ld = 8'b00000000;
////////////////////////////其它/////////////////////////////
//-----Control_Data-----
always @ (reset or Control_Flag or ModeA or ModeB or PortA_IO or PortB_IO)
if(reset) //輸出給PC_IO的控制信號;
Control_Data = 7'b0000000;
else
Control_Data = {PortC_RS,Control_Flag,ModeA,ModeB,PortA_IO,PortB_IO};
//-----Dout_Select----- //輸出給Dout_Mux的選擇信號;
always @ (reset or A or nRD)
if(reset)
Dout_Select = 2'b00;
else if(nRD==1'b0)
case(A)
2'b00: Dout_Select = 2'b00;
2'b01: Dout_Select = 2'b01;
2'b10: Dout_Select = 2'b10;
default: Dout_Select = 2'b00;
endcase
else
Dout_Select = Dout_Select;
endmodule
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -