📄 cpu.v
字号:
parameter[7:0] ACALL_5 = 8'b10110001;
parameter[7:0] CPL_BIT = 8'b10110010;
parameter[7:0] CPL_C = 8'b10110011;
parameter[7:0] CJNE_A_N = 8'b10110100;
parameter[7:0] CJNE_A_ADDR = 8'b10110101;
parameter[7:0] CJNE_IR0_N = 8'b10110110;
parameter[7:0] CJNE_IR1_N = 8'b10110111;
parameter[7:0] CJNE_R0_N = 8'b10111000;
parameter[7:0] CJNE_R1_N = 8'b10111001;
parameter[7:0] CJNE_R2_N = 8'b10111010;
parameter[7:0] CJNE_R3_N = 8'b10111011;
parameter[7:0] CJNE_R4_N = 8'b10111100;
parameter[7:0] CJNE_R5_N = 8'b10111101;
parameter[7:0] CJNE_R6_N = 8'b10111110;
parameter[7:0] CJNE_R7_N = 8'b10111111;
// C0H - CFh
parameter[7:0] PUSH = 8'b11000000;
parameter[7:0] AJMP_6 = 8'b11000001;
parameter[7:0] CLR_BIT = 8'b11000010;
parameter[7:0] CLR_C = 8'b11000011;
parameter[7:0] SWAP_A = 8'b11000100;
parameter[7:0] XCH_ADDR = 8'b11000101;
parameter[7:0] XCH_IR0 = 8'b11000110;
parameter[7:0] XCH_IR1 = 8'b11000111;
parameter[7:0] XCH_R0 = 8'b11001000;
parameter[7:0] XCH_R1 = 8'b11001001;
parameter[7:0] XCH_R2 = 8'b11001010;
parameter[7:0] XCH_R3 = 8'b11001011;
parameter[7:0] XCH_R4 = 8'b11001100;
parameter[7:0] XCH_R5 = 8'b11001101;
parameter[7:0] XCH_R6 = 8'b11001110;
parameter[7:0] XCH_R7 = 8'b11001111;
// D0H - DFh
parameter[7:0] POP = 8'b11010000;
parameter[7:0] ACALL_6 = 8'b11010001;
parameter[7:0] SETB_BIT = 8'b11010010;
parameter[7:0] SETB_C = 8'b11010011;
parameter[7:0] DA_A = 8'b11010100;
parameter[7:0] DJNZ_ADDR = 8'b11010101;
parameter[7:0] XCHD_IR0 = 8'b11010110;
parameter[7:0] XCHD_IR1 = 8'b11010111;
parameter[7:0] DJNZ_R0 = 8'b11011000;
parameter[7:0] DJNZ_R1 = 8'b11011001;
parameter[7:0] DJNZ_R2 = 8'b11011010;
parameter[7:0] DJNZ_R3 = 8'b11011011;
parameter[7:0] DJNZ_R4 = 8'b11011100;
parameter[7:0] DJNZ_R5 = 8'b11011101;
parameter[7:0] DJNZ_R6 = 8'b11011110;
parameter[7:0] DJNZ_R7 = 8'b11011111;
// E0H - EFh
parameter[7:0] MOVX_A_IDPTR = 8'b11100000;
parameter[7:0] AJMP_7 = 8'b11100001;
parameter[7:0] MOVX_A_IR0 = 8'b11100010;
parameter[7:0] MOVX_A_IR1 = 8'b11100011;
parameter[7:0] CLR_A = 8'b11100100;
parameter[7:0] MOV_A_ADDR = 8'b11100101;
parameter[7:0] MOV_A_IR0 = 8'b11100110;
parameter[7:0] MOV_A_IR1 = 8'b11100111;
parameter[7:0] MOV_A_R0 = 8'b11101000;
parameter[7:0] MOV_A_R1 = 8'b11101001;
parameter[7:0] MOV_A_R2 = 8'b11101010;
parameter[7:0] MOV_A_R3 = 8'b11101011;
parameter[7:0] MOV_A_R4 = 8'b11101100;
parameter[7:0] MOV_A_R5 = 8'b11101101;
parameter[7:0] MOV_A_R6 = 8'b11101110;
parameter[7:0] MOV_A_R7 = 8'b11101111;
// F0H - FFh
parameter[7:0] MOVX_IDPTR_A = 8'b11110000;
parameter[7:0] ACALL_7 = 8'b11110001;
parameter[7:0] MOVX_IR0_A = 8'b11110010;
parameter[7:0] MOVX_IR1_A = 8'b11110011;
parameter[7:0] CPL_A = 8'b11110100;
parameter[7:0] MOV_ADDR_A = 8'b11110101;
parameter[7:0] MOV_IR0_A = 8'b11110110;
parameter[7:0] MOV_IR1_A = 8'b11110111;
parameter[7:0] MOV_R0_A = 8'b11111000;
parameter[7:0] MOV_R1_A = 8'b11111001;
parameter[7:0] MOV_R2_A = 8'b11111010;
parameter[7:0] MOV_R3_A = 8'b11111011;
parameter[7:0] MOV_R4_A = 8'b11111100;
parameter[7:0] MOV_R5_A = 8'b11111101;
parameter[7:0] MOV_R6_A = 8'b11111110;
parameter[7:0] MOV_R7_A = 8'b11111111;
//-----------------------------------------------------------------
// Interrupt reset values
//-----------------------------------------------------------------
parameter[4:0] VECT_RV = 5'b00000; // Interrupt Vector reset value
parameter[3:0] IS_REG_RV = 4'b0000; // In Service Register reset value
//-----------------------------------------------------------------
// Interrupt Vector locations
//-----------------------------------------------------------------
// external interrupt 0
parameter[4:0] VECT_E0 = 5'b00000;
// timer 0 overflow
parameter[4:0] VECT_TF0 = 5'b00001;
// external interrupt 1
parameter[4:0] VECT_E1 = 5'b00010;
// timer 1 overflow
parameter[4:0] VECT_TF1 = 5'b00011;
// serial channel 0
parameter[4:0] VECT_SER0 = 5'b00100;
// timer 2 overflow/ext. reload
parameter[4:0] VECT_TF2 = 5'b00101;
// A/D converter
parameter[4:0] VECT_ADC = 5'b01000;
// external interrupt 2
parameter[4:0] VECT_EX2 = 5'b01001;
// external interrupt 3
parameter[4:0] VECT_EX3 = 5'b01010;
// external interrupt 4
parameter[4:0] VECT_EX4 = 5'b01011;
// external interrupt 5
parameter[4:0] VECT_EX5 = 5'b01100;
// external interrupt 6
parameter[4:0] VECT_EX6 = 5'b01101;
// serial channel 1
parameter[4:0] VECT_SER1 = 5'b10000;
//-----------------------------------------------------------------
// Start address location
//-----------------------------------------------------------------
parameter[15:0] ADDR_RV = 16'b0000000000000000; //
//-----------------------------------------------------------------
// RAM & SFR address reset value
//-----------------------------------------------------------------
parameter[7:0] RAM_SFR_ADDR_RV= 8'b00000000; //
//-----------------------------------------------------------------
// Data register reset value
//-----------------------------------------------------------------
parameter[7:0] DATAREG_RV = 8'b00000000; //
//-----------------------------------------------------------------
// High ordered half of address during indirect addressing
//-----------------------------------------------------------------
parameter[7:0] ADDR_HIGH_RI = 8'b00000000; //
//-----------------------------------------------------------------
// Watchdog Timer reset value
//-----------------------------------------------------------------
parameter[6:0] WDTH_RV = 7'b0000000; // High ordered WDT
parameter[7:0] WDTL_RV = 8'b00000000; // Low ordered WDT
//-----------------------------------------------------------------
// Watchdog Timer reset state
//-----------------------------------------------------------------
parameter[14:0] WDT_RS = 15'b111111111111100; // X"7FFC"
//*******************************************************************--
// Control signal inputs
input clk; // Global clock input
input rst; // Global reset input
// External memory read/write acknowledge input
input mempsackint;
input memackint;
// ISR input signals
input intreq; // Interrupt request
// Clock Control inputs
input [2:0] stretch;
// Power Management Unit input
input stoppmu; // Stop mode
// OCI input signals
input debugreq;
input debugack;
input debugstep;
input a5instr;
// debug fetch enable
output debugfetche;
// Instruction register output
output [7:0] instr;
wire [7:0] instr;
// Cycle counter output
output [3:0] cycle;
wire [3:0] cycle;
output [3:0] nrcycles;
// Instruction decoder output
output codefetche; // Opcode fetch enable
wire codefetche;
output datafetche; // Data fetch enable
wire datafetche;
output rmwinstr; // Read-Modify-Write Instr.
reg rmwinstr;
output intack; // Interrupt acknowledge flag
// ISR control outputs
reg intack;
output intret; // Interrupt return flag
reg intret;
output intcall; // Interrupt call
wire intcall;
// Program bus input
input [7:0] memdatai;
// sfr write enable
input sfrwe;
//------------------------------------------------------------------
// Instruction register
reg [7:0] instrreg;
// Fetch enable signals
wire debug_fetch_e;
wire code_fetch_e;
wire data_fetch_e;
// Current machine cycle register
reg [3:0] curcycle;
// Number of bytes and cycles signals
reg [3:0] nr_cycles_a;
reg [1:0] nr_bytes_a;
// Number of bytes and cycles registers
reg [3:0] nr_cycles;
reg [1:0] nr_bytes;
// Read-Modify-Write Instruction signal
wire rmwinstr_a;
// Interrupt call routine flag
reg int_call;
//------------------------------------------------------------------
// Instruction opcode
//------------------------------------------------------------------
assign instr = instrreg ;
//------------------------------------------------------------------
// Current machine cycle
//------------------------------------------------------------------
assign cycle = curcycle ;
//------------------------------------------------------------------
// Number of machine cycles
//------------------------------------------------------------------
assign nrcycles = nr_cycles ;
//------------------------------------------------------------------
// Opcode fetch enable signals for debug mode
//------------------------------------------------------------------
assign debugfetche = debug_fetch_e ;
//------------------------------------------------------------------
// Opcode fetch enable signals
//------------------------------------------------------------------
assign codefetche = code_fetch_e ;
//------------------------------------------------------------------
// Data fetch enable signals
//------------------------------------------------------------------
assign datafetche = data_fetch_e ;
//------------------------------------------------------------------
// Interrupt call
//------------------------------------------------------------------
assign intcall = int_call ;
//------------------------------------------------------------------
always @(posedge clk)
begin : interrupt_proc
//------------------------------------------------------------------
if (rst)
//-----------------------------------
// Synchronous reset
//-----------------------------------
begin
intack <= 1'b0 ;
intret <= 1'b0 ;
int_call <= 1'b0 ;
end
else
//-----------------------------------
// Synchronous write
//-----------------------------------
// Interrupt call flag
//--------------------------------
begin
if (code_fetch_e & mempsackint)
begin
if (intreq)
begin
int_call <= 1'b1 ;
end
else
begin
int_call <= 1'b0 ;
end
end
//--------------------------------
// Interrupt acknowledge flag
//--------------------------------
if (int_call & curcycle == 4'b 0011) // active cycle=4
begin
intack <= 1'b1 ;
end
else
begin
intack <= 1'b0 ;
end
//--------------------------------
// Interrupt return flag
//--------------------------------
if (instrreg == RETI & curcycle == 4'b 0011) // active cycle=4
begin
intret <= 1'b1 ;
end
else
begin
intret <= 1'b0 ;
end
end
end
//------------------------------------------------------------------
// Instruction code fetch enable for debug mode
//------------------------------------------------------------------
assign debug_fetch_e = (debugack & debugstep) ? 1'b1 : 1'b0 ;
//------------------------------------------------------------------
// Instruction code fetch enable
//------------------------------------------------------------------
assign code_fetch_e = (curcycle == nr_cycles &
~stoppmu & ~a5instr & ~debugreq) ? 1'b1
: 1'b0 ;
//------------------------------------------------------------------
// Instruction data fetch enable
//------------------------------------------------------------------
assign data_fetch_e = (curcycle < nr_bytes) ? 1'b1 : 1'b0 ;
//------------------------------------------------------------------
// Instruction register
//------------------------------------------------------------------
always @(posedge clk)
begin : codefetch_proc
//------------------------------------------------------------------
if (rst)
//-----------------------------------
// Synchronous reset
//-----------------------------------
begin
instrreg <= NOP ;
end
else
//-----------------------------------
// Synchronous write
//-----------------------------------
// Instruction register write
//--------------------------------
begin
if (stoppmu)
begin
instrreg <= NOP;
end
else if ((code_fetch_e | debug_fetch_e) & mempsackint)
begin
if (intreq)
begin
// Interrupt request
instrreg <= LCALL ;
end
else
begin
instrreg <= memdatai ;
end
end
else if ((curcycle==nr_cycles) & (a5instr | debugreq))
begin
instrreg <= NOP;
end
end
end
//------------------------------------------------------------------
// Current cycle counter
//------------------------------------------------------------------
always @(posedge clk)
begin : curcycle_proc
//------------------------------------------------------------------
if (rst)
//-----------------------------------
// Synchronous reset
//-----------------------------------
begin
curcycle <= 4'b 0001 ;
end
else
begin
//-----------------------------------
// Synchronous write
//-----------------------------------
// Current cycle count
//--------------------------------
if (mempsackint & memackint)
begin
if (curcycle < nr_cycles)
begin
curcycle <= curcycle + 4'b 0001 ;
end
else
begin
curcycle <= 4'b 0001 ;
end
end
end
end
//------------------------------------------------------------------
// Read-Modify-Write instruction decoder
// Combinational part
//------------------------------------------------------------------
assign rmwinstr_a =
(memdatai == ANL_ADDR_A | memdatai == ANL_ADDR_N |
memdatai == ORL_ADDR_A | memdatai == ORL_ADDR_N |
memdatai == XRL_ADDR_A | memdatai == XRL_ADDR_N |
memdatai == JBC_BIT | memdatai == CPL_BIT |
memdatai == INC_ADDR | memdatai == DEC_ADDR |
memdatai == DJNZ_ADDR | memdatai == MOV_BIT_C |
memdatai == CLR_BIT | memdatai == SETB_BIT) ? 1'b1
: 1'b0 ;
//------------------------------------------------------------------
// Read-Modify-Write instruction decoder
// Sequential part
//------------------------------------------------------------------
always @(posedge clk)
begin : rmwinstr_decoder_proc
//------------------------------------------------------------------
if (rst)
//-----------------------------------
// Synchronous reset
//-----------------------------------
begin
rmwinstr <= 1'b0 ;
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -