📄 it51_core.v
字号:
//-----------------------------------------------------------------------------
// IT51 (Improved-T51) --
// --
// VERSION: 030723 --
// --
// Contact: yfchen58@gmail.com --
// --
//-----------------------------------------------------------------------------
// --
// IT51 - Improved T51 (VHDL 1-Cycle 8051 Compatible Microcontroller) --
// Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --
// Yung-Fu Chen (yfchen58@ms49.hinet.net) --
// --
//-----------------------------------------------------------------------------
// FETURE --
// . IT51_top interface is similar to synopsys DW8051 --
// . High-Performance 1-Cycle 8051 --
// . instruction compatible with standard DW8051 --
// . 256 byte internal data memory --
// . up to 64KB external data memory --
// . up to 64KB internal program memory --
// . export sfr-bus --
// . no dual-port memory used --
// . no watch-dog timer --
// . dual DPTR (DPTR0, DPTR1), refer to DW8051 --
// . sleep mode support, refer to DW8051 --
// . no stop mode --
// . six external interrupt, refer to DW8051 --
// . pass all DW8051 test-pattern --
// . UART/Timer are not fully tested yet --
// . no internal tri-state bus --
// . 2-Cycle MUL Instruction --
// --
//-----------------------------------------------------------------------------
// --
// IT51_top (Interface Compatible with Synopsys DW8051) --
// | --
// +-- IT51_core (Control Unit) --
// | | --
// | +-- IT51_ALU (ALU) --
// | | --
// | +-- IT51_MD (MUL/DIV) --
// | --
// +-- IT51_Glue (Glue Logic) --
// | --
// +-- IT51_TC01 (Timer/Counter-1) --
// | --
// +-- IT51_TC2 (Timer/Counter-2) --
// | --
// +-- IT51_UART (UART) --
// --
//-----------------------------------------------------------------------------
// ============================================================================
// The original T51 license is listed below:
// ============================================================================
//
// 8051 compatible microcontroller core
//
// Version : 0218
//
// Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
//
// All rights reserved
//
// Redistribution and use in source and synthezised forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// Redistributions in synthesized form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Please report bugs to the author, but before you do so, please
// make sure that this is not a derivative work and that
// you have the latest version of this file.
//
// The latest version of this file can be found at:
// http://www.opencores.org/cvsweb.shtml/t51/
//
// Limitations :
//
// File history :
//
// ============================================================================
//
//`define DPH0 DPTR0[15:8]
//`define DPL0 DPTR0[7:0]
//`define DPH1 DPTR1[15:8]
//`define DPL1 DPTR1[7:0]
//`define DPS_SEL DPS[0]
//`define cInst_Length cInst_MCode[1:0]
//`define nInst ROM_Data
//`define nInst_Rn_Index ROM_Data[2:0]
module IT51_core (Clk, Rst_n, Idle_n, ROM_Addr, ROM_Data, RAM_Addr, RAM_RData, RAM_WData, RAM_Cycle, RAM_Rd, RAM_Wr, iRAM_Addr, iRAM_Rd, iRAM_Wr, iRAM_RData, iRAM_WData, Int_Trig, Int_Acc, SFR_Rd, SFR_Wr, SFR_Addr, SFR_WData, SFR_RData_Ext);
// included from package it51_pack
input Clk;
input Rst_n;
input Idle_n;
output[15:0] ROM_Addr;
wire[15:0] ROM_Addr;
input[7:0] ROM_Data;
output[15:0] RAM_Addr;
reg[15:0] RAM_Addr;
input[7:0] RAM_RData;
output[7:0] RAM_WData;
wire[7:0] RAM_WData;
output RAM_Cycle;
wire RAM_Cycle;
output RAM_Rd;
wire RAM_Rd;
output RAM_Wr;
wire RAM_Wr;
output[7:0] iRAM_Addr;
wire[7:0] iRAM_Addr;
output iRAM_Rd;
wire iRAM_Rd;
output iRAM_Wr;
wire iRAM_Wr;
input[7:0] iRAM_RData;
output[7:0] iRAM_WData;
wire[7:0] iRAM_WData;
input[10:0] Int_Trig;
output[10:0] Int_Acc;
reg[10:0] Int_Acc;
output SFR_Rd;
wire SFR_Rd;
output SFR_Wr;
wire SFR_Wr;
output[6:0] SFR_Addr;
wire[6:0] SFR_Addr;
output[7:0] SFR_WData;
wire[7:0] SFR_WData;
input[7:0] SFR_RData_Ext;
// Registers
reg[7:0] ACC;
reg[7:0] B;
reg[7:1] PSW; // Bit 0 is parity
wire PSW0;
reg[7:0] IP;
reg[7:0] SP;
reg[7:0] iSP;
reg[15:0] DPTR0; // DPTR0
wire[15:0] DPTR0_Plus_ACC;
reg[15:0] DPTR1; // DPTR1
wire[15:0] DPTR1_Plus_ACC;
reg[7:0] DPS; // DPS
reg[7:0] CKCON; // CKCON
reg[15:0] PC;
reg[15:0] PC_Plus_1;
reg[15:0] PC_Plus_2;
reg[15:0] PC_Minus_1;
reg[15:0] PC_Plus_cInst1;
reg[15:0] PC_Plus_cInst2;
reg[7:0] MPAGE;
reg[15:0] PCC;
reg[15:0] nPC;
reg[15:0] oPC;
// ALU signals
wire[7:0] Op_A;
wire[7:0] Op_B;
reg[7:0] Mem_A;
reg Mem_A_Rd;
wire[7:0] Mem_Din;
reg[7:0] Old_Mem_A;
wire[7:0] ACC_Q;
wire[7:0] B_Q;
wire[7:0] Res_Bus;
wire[7:5] Status_D;
wire[7:5] Status_Wr;
// Misc signals
reg[7:0] Int_AddrA;
reg[7:0] Int_AddrA_r;
wire Last;
reg[1:0] FCycle;
reg RET_r;
wire Next_PSW7;
wire Next_ACC_Z;
reg ACC_Wr;
reg B_Wr;
reg[7:0] SFR_RData;
reg[7:0] SFR_RData_r;
reg[7:0] Bit_Pattern;
// Registered instruction words.
reg[7:0] cInst;
reg[7:0] cInst1;
reg[7:0] cInst2;
reg[8:0] cInst_MCode;
reg[8:0] nInst_MCode;
// Control signals
reg RAM_Rd_i;
reg RAM_Wr_i;
reg Rst_r_n;
reg SFR_Rd_i;
reg SFR_Wr_i;
reg SFR_Wr_p;
reg Mem_Wr;
reg Mem_Wr_p;
reg J_Skip;
reg IPending;
reg[10:0] Int_Trig_r;
reg ICall;
reg HPInt;
reg LPInt;
reg[3:0] PCPaused;
wire Div_Rdy;
reg INC_DPTR;
wire CJNE;
wire DJNZ;
// Mux control
reg AMux_SFR;
reg BMux_Inst2;
reg RMux_PCL;
reg RMux_PCH;
reg INT_reject;
wire First_Cycle;
wire Second_Cycle;
wire Third_Cycle;
wire Last_Cycle;
wire Inst_Skip;
wire IStart;
wire Ri_Stall;
wire PSW_Stall;
wire RW_Stall;
reg PCPause;
wire Ready;
reg NOP;
wire nInst_is_Ri;
wire nInst_is_Rn;
wire nInst_is_RET;
wire nInst_is_RETI;
wire nInst_is_DR;
reg cInst_is_DW;
reg cInst_is_MOVX_Write;
reg cInst_is_MOVX_Read;
reg cInst_is_RET;
reg cInst_is_RETI;
reg cInst_is_MOVC;
reg cInst_is_DIV;
reg cInst_is_PUSH;
reg cInst_is_POP;
reg cInst_is_ACALL;
reg cInst_is_LCALL;
reg cInst_is_Ri;
reg cInst_is_Rn;
reg cInst_is_A_Write;
reg cInst_is_MUL;
reg cInst_is_INC_DPTR;
reg cInst_is_JC;
reg cInst_is_JNC;
reg cInst_is_JZ;
reg cInst_is_JNZ;
reg cInst_is_SJMP;
reg cInst_is_AJMP;
reg cInst_is_JB;
reg cInst_is_JNB;
reg cInst_is_JBC;
reg cInst_is_LJMP;
reg cInst_is_IW;
reg cInst_is_DR;
reg cInst_is_CJNE;
reg cInst_is_DJNE;
reg cInst_is_DJNZ;
reg cInst_is_JMP_A_DPTR;
reg cInst_is_7x;
reg cInst_is_8x;
reg cInst_is_Ax;
reg cInst_is_x3;
reg cInst_is_x5;
reg[7:0] EIP;
wire[10:0] INT_IP;
reg[15:0] IRQ_Entry;
//--------------------------------------------------------------------------
assign iRAM_Rd = Mem_A_Rd ;
assign iRAM_Wr = Mem_Wr ;
assign iRAM_WData = Mem_Din ;
assign iRAM_Addr = (Mem_Wr == 1'b1) ? Int_AddrA_r : Int_AddrA ;
always @(negedge Rst_n or posedge Clk)
begin
if (Rst_n == 1'b0)
begin
Mem_A <= {8{1'b0}} ;
end
else
begin
if (Mem_A_Rd == 1'b1)
begin
Mem_A <= iRAM_RData ;
end
if (Mem_Wr == 1'b1)
begin
if (Int_AddrA_r == Int_AddrA)
begin
Mem_A <= Mem_Din ;
end
end
end
end
//--------------------------------------------------------------------------
assign ROM_Addr = nPC ;
//--------------------------------------------------------------------------
// Ready
assign Ready = (Idle_n == 1'b1) ;
//--------------------------------------------------------------------------
// Next Instruction is @Ri
assign nInst_is_Ri = ((nInst_MCode[7]) == 1'b1) ;
assign nInst_is_Rn = ((nInst_MCode[8]) == 1'b1) ;
//assign nInst_is_RET = (nInst == 8'b00100010) ;
assign nInst_is_RET = (ROM_Data == 8'b00100010) ;
assign nInst_is_RETI = (ROM_Data == 8'b00110010) ;
assign nInst_is_DR = ((nInst_MCode[5]) == 1'b1) ;
//--------------------------------------------------------------------------
// Program counter
//PC_Plus_1 <= PC + 1;
//PC_Plus_2 <= PC + 2;
//PC_Minus_1 <= PC - 1;
//PC_Plus_cInst1 <= std_logic_vector(conv_unsigned(signed(PC) +
// signed(cInst1), 16));
//PC_Plus_cInst2 <= std_logic_vector(conv_unsigned(signed(PC) +
// signed(cInst2), 16));
always @(negedge Rst_n or posedge Clk)
begin
if (Rst_n == 1'b0)
begin
PC <= {16{1'b0}} ;
PC_Plus_1 <= 16'b0000000000000001 ;
PC_Plus_2 <= 16'b0000000000000010 ;
PC_Minus_1 <= 16'b1111111111111111 ;
end
else
begin
if (Ready)
begin
PC <= nPC ;
PC_Plus_1 <= nPC + 1 ;
PC_Plus_2 <= nPC + 2 ;
PC_Minus_1 <= nPC - 1 ;
end
end
end
// PC_Plus_cInst1
always @(negedge Rst_n or posedge Clk)
begin
if (Rst_n == 1'b0)
begin
PC_Plus_cInst1 <= {16{1'b0}} ;
end
else
begin
if (Ready)
begin
if (First_Cycle)
begin
//PC_Plus_cInst1 <= std_logic_vector(signed(nPC) + signed(nInst)) ;
PC_Plus_cInst1 <= nPC + ROM_Data ;
end
else
begin
//PC_Plus_cInst1 <= std_logic_vector(signed(nPC) + signed(cInst1)) ;
PC_Plus_cInst1 <= nPC + cInst1 ;
end
end
end
end
// PC_Plus_cInst2
always @(negedge Rst_n or posedge Clk)
begin
if (Rst_n == 1'b0)
begin
PC_Plus_cInst2 <= {16{1'b0}} ;
end
else
begin
if (Ready)
begin
if (Second_Cycle)
begin
//PC_Plus_cInst2 <= std_logic_vector(signed(nPC) + signed(nInst)) ;
PC_Plus_cInst2 <= nPC + ROM_Data;
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -