OpenCores
URL https://opencores.org/ocsvn/turbo8051/turbo8051/trunk

Subversion Repositories turbo8051

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 67 to Rev 68
    Reverse comparison

Rev 67 → Rev 68

/turbo8051/trunk/rtl/8051/oc8051_defines.v
1,532 → 1,533
//////////////////////////////////////////////////////////////////////
//// ////
//// 8051 cores Definitions ////
//// ////
//// This file is part of the 8051 cores project ////
//// http://www.opencores.org/cores/8051/ ////
//// ////
//// Description ////
//// 8051 definitions. ////
//// ////
//// To Do: ////
//// Nothing ////
//// ////
//// Author(s): ////
//// - Simon Teran, simont@opencores.org ////
//// - Jaka Simsic, jakas@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// ver: 1
//
 
//
// oc8051 pherypherals
//
//`define OC8051_UART
`define OC8051_TC01
`define OC8051_TC2
`define OC8051_PORTS //ports global enable
`define OC8051_PORT0
`define OC8051_PORT1
`define OC8051_PORT2
`define OC8051_PORT3
 
 
//
// oc8051 ITERNAL ROM
//
`define OC8051_ROM
 
 
//
// oc8051 memory
//
//`define OC8051_CACHE
//`define OC8051_WB
 
//`define OC8051_RAM_XILINX
//`define OC8051_RAM_VIRTUALSILICON
//`define OC8051_RAM_GENERIC
 
 
//`define OC8051_XILINX_ROM
 
//
// oc8051 simulation defines
//
//`define OC8051_SIMULATION
//`define OC8051_SERIAL
 
//
// oc8051 bist
//
//`define OC8051_BIST
 
 
//
// operation codes for alu
//
 
 
`define OC8051_ALU_NOP 4'b0000
`define OC8051_ALU_ADD 4'b0001
`define OC8051_ALU_SUB 4'b0010
`define OC8051_ALU_MUL 4'b0011
`define OC8051_ALU_DIV 4'b0100
`define OC8051_ALU_DA 4'b0101
`define OC8051_ALU_NOT 4'b0110
`define OC8051_ALU_AND 4'b0111
`define OC8051_ALU_XOR 4'b1000
`define OC8051_ALU_OR 4'b1001
`define OC8051_ALU_RL 4'b1010
`define OC8051_ALU_RLC 4'b1011
`define OC8051_ALU_RR 4'b1100
`define OC8051_ALU_RRC 4'b1101
`define OC8051_ALU_INC 4'b1110
`define OC8051_ALU_XCH 4'b1111
 
//
// sfr addresses
//
 
`define OC8051_SFR_ACC 8'he0 //accumulator
`define OC8051_SFR_B 8'hf0 //b register
`define OC8051_SFR_PSW 8'hd0 //program status word
`define OC8051_SFR_P0 8'h80 //port 0
`define OC8051_SFR_P1 8'h90 //port 1
`define OC8051_SFR_P2 8'ha0 //port 2
`define OC8051_SFR_P3 8'hb0 //port 3
`define OC8051_SFR_DPTR_LO 8'h82 // data pointer high bits
`define OC8051_SFR_DPTR_HI 8'h83 // data pointer low bits
`define OC8051_SFR_IP0 8'hb8 // interrupt priority
`define OC8051_SFR_IEN0 8'ha8 // interrupt enable 0
`define OC8051_SFR_TMOD 8'h89 // timer/counter mode
`define OC8051_SFR_TCON 8'h88 // timer/counter control
`define OC8051_SFR_TH0 8'h8c // timer/counter 0 high bits
`define OC8051_SFR_TL0 8'h8a // timer/counter 0 low bits
`define OC8051_SFR_TH1 8'h8d // timer/counter 1 high bits
`define OC8051_SFR_TL1 8'h8b // timer/counter 1 low bits
 
`define OC8051_SFR_SCON 8'h98 // serial control 0
`define OC8051_SFR_SBUF 8'h99 // serial data buffer 0
`define OC8051_SFR_SADDR 8'ha9 // serila address register 0
`define OC8051_SFR_SADEN 8'hb9 // serila address enable 0
 
`define OC8051_SFR_PCON 8'h87 // power control
`define OC8051_SFR_SP 8'h81 // stack pointer
 
 
 
`define OC8051_SFR_IE 8'ha8 // interrupt enable
`define OC8051_SFR_IP 8'hb7 // interrupt priority
 
`define OC8051_SFR_RCAP2H 8'hcb // timer 2 capture high
`define OC8051_SFR_RCAP2L 8'hca // timer 2 capture low
 
`define OC8051_SFR_T2CON 8'hc8 // timer 2 control register
`define OC8051_SFR_TH2 8'hcd // timer 2 high
`define OC8051_SFR_TL2 8'hcc // timer 2 low
 
 
 
//
// sfr bit addresses
//
`define OC8051_SFR_B_ACC 5'b11100 //accumulator
`define OC8051_SFR_B_PSW 5'b11010 //program status word
`define OC8051_SFR_B_P0 5'b10000 //port 0
`define OC8051_SFR_B_P1 5'b10010 //port 1
`define OC8051_SFR_B_P2 5'b10100 //port 2
`define OC8051_SFR_B_P3 5'b10110 //port 3
`define OC8051_SFR_B_B 5'b11110 // b register
`define OC8051_SFR_B_IP 5'b10111 // interrupt priority control 0
`define OC8051_SFR_B_IE 5'b10101 // interrupt enable control 0
`define OC8051_SFR_B_SCON 5'b10011 // serial control
`define OC8051_SFR_B_TCON 5'b10001 // timer/counter control
`define OC8051_SFR_B_T2CON 5'b11001 // timer/counter2 control
 
 
//
//carry input in alu
//
`define OC8051_CY_0 2'b00 // 1'b0;
`define OC8051_CY_PSW 2'b01 // carry from psw
`define OC8051_CY_RAM 2'b10 // carry from ram
`define OC8051_CY_1 2'b11 // 1'b1;
`define OC8051_CY_DC 2'b00 // carry from psw
 
//
// instruction set
//
 
//op_code [4:0]
`define OC8051_ACALL 8'bxxx1_0001 // absolute call
`define OC8051_AJMP 8'bxxx0_0001 // absolute jump
 
//op_code [7:3]
`define OC8051_ADD_R 8'b0010_1xxx // add A=A+Rx
`define OC8051_ADDC_R 8'b0011_1xxx // add A=A+Rx+c
`define OC8051_ANL_R 8'b0101_1xxx // and A=A^Rx
`define OC8051_CJNE_R 8'b1011_1xxx // compare and jump if not equal; Rx<>constant
`define OC8051_DEC_R 8'b0001_1xxx // decrement reg Rn=Rn-1
`define OC8051_DJNZ_R 8'b1101_1xxx // decrement and jump if not zero
`define OC8051_INC_R 8'b0000_1xxx // increment Rn
`define OC8051_MOV_R 8'b1110_1xxx // move A=Rn
`define OC8051_MOV_AR 8'b1111_1xxx // move Rn=A
`define OC8051_MOV_DR 8'b1010_1xxx // move Rn=(direct)
`define OC8051_MOV_CR 8'b0111_1xxx // move Rn=constant
`define OC8051_MOV_RD 8'b1000_1xxx // move (direct)=Rn
`define OC8051_ORL_R 8'b0100_1xxx // or A=A or Rn
`define OC8051_SUBB_R 8'b1001_1xxx // substract with borrow A=A-c-Rn
`define OC8051_XCH_R 8'b1100_1xxx // exchange A<->Rn
`define OC8051_XRL_R 8'b0110_1xxx // XOR A=A XOR Rn
 
//op_code [7:1]
`define OC8051_ADD_I 8'b0010_011x // add A=A+@Ri
`define OC8051_ADDC_I 8'b0011_011x // add A=A+@Ri+c
`define OC8051_ANL_I 8'b0101_011x // and A=A^@Ri
`define OC8051_CJNE_I 8'b1011_011x // compare and jump if not equal; @Ri<>constant
`define OC8051_DEC_I 8'b0001_011x // decrement indirect @Ri=@Ri-1
`define OC8051_INC_I 8'b0000_011x // increment @Ri
`define OC8051_MOV_I 8'b1110_011x // move A=@Ri
`define OC8051_MOV_ID 8'b1000_011x // move (direct)=@Ri
`define OC8051_MOV_AI 8'b1111_011x // move @Ri=A
`define OC8051_MOV_DI 8'b1010_011x // move @Ri=(direct)
`define OC8051_MOV_CI 8'b0111_011x // move @Ri=constant
`define OC8051_MOVX_IA 8'b1110_001x // move A=(@Ri)
`define OC8051_MOVX_AI 8'b1111_001x // move (@Ri)=A
`define OC8051_ORL_I 8'b0100_011x // or A=A or @Ri
`define OC8051_SUBB_I 8'b1001_011x // substract with borrow A=A-c-@Ri
`define OC8051_XCH_I 8'b1100_011x // exchange A<->@Ri
`define OC8051_XCHD 8'b1101_011x // exchange digit A<->Ri
`define OC8051_XRL_I 8'b0110_011x // XOR A=A XOR @Ri
 
//op_code [7:0]
`define OC8051_ADD_D 8'b0010_0101 // add A=A+(direct)
`define OC8051_ADD_C 8'b0010_0100 // add A=A+constant
`define OC8051_ADDC_D 8'b0011_0101 // add A=A+(direct)+c
`define OC8051_ADDC_C 8'b0011_0100 // add A=A+constant+c
`define OC8051_ANL_D 8'b0101_0101 // and A=A^(direct)
`define OC8051_ANL_C 8'b0101_0100 // and A=A^constant
`define OC8051_ANL_DD 8'b0101_0010 // and (direct)=(direct)^A
`define OC8051_ANL_DC 8'b0101_0011 // and (direct)=(direct)^constant
`define OC8051_ANL_B 8'b1000_0010 // and c=c^bit
`define OC8051_ANL_NB 8'b1011_0000 // and c=c^!bit
`define OC8051_CJNE_D 8'b1011_0101 // compare and jump if not equal; a<>(direct)
`define OC8051_CJNE_C 8'b1011_0100 // compare and jump if not equal; a<>constant
`define OC8051_CLR_A 8'b1110_0100 // clear accumulator
`define OC8051_CLR_C 8'b1100_0011 // clear carry
`define OC8051_CLR_B 8'b1100_0010 // clear bit
`define OC8051_CPL_A 8'b1111_0100 // complement accumulator
`define OC8051_CPL_C 8'b1011_0011 // complement carry
`define OC8051_CPL_B 8'b1011_0010 // complement bit
`define OC8051_DA 8'b1101_0100 // decimal adjust (A)
`define OC8051_DEC_A 8'b0001_0100 // decrement accumulator a=a-1
`define OC8051_DEC_D 8'b0001_0101 // decrement direct (direct)=(direct)-1
`define OC8051_DIV 8'b1000_0100 // divide
`define OC8051_DJNZ_D 8'b1101_0101 // decrement and jump if not zero (direct)
`define OC8051_INC_A 8'b0000_0100 // increment accumulator
`define OC8051_INC_D 8'b0000_0101 // increment (direct)
`define OC8051_INC_DP 8'b1010_0011 // increment data pointer
`define OC8051_JB 8'b0010_0000 // jump if bit set
`define OC8051_JBC 8'b0001_0000 // jump if bit set and clear bit
`define OC8051_JC 8'b0100_0000 // jump if carry is set
`define OC8051_JMP_D 8'b0111_0011 // jump indirect
`define OC8051_JNB 8'b0011_0000 // jump if bit not set
`define OC8051_JNC 8'b0101_0000 // jump if carry not set
`define OC8051_JNZ 8'b0111_0000 // jump if accumulator not zero
`define OC8051_JZ 8'b0110_0000 // jump if accumulator zero
`define OC8051_LCALL 8'b0001_0010 // long call
`define OC8051_LJMP 8'b0000_0010 // long jump
`define OC8051_MOV_D 8'b1110_0101 // move A=(direct)
`define OC8051_MOV_C 8'b0111_0100 // move A=constant
`define OC8051_MOV_DA 8'b1111_0101 // move (direct)=A
`define OC8051_MOV_DD 8'b1000_0101 // move (direct)=(direct)
`define OC8051_MOV_CD 8'b0111_0101 // move (direct)=constant
`define OC8051_MOV_BC 8'b1010_0010 // move c=bit
`define OC8051_MOV_CB 8'b1001_0010 // move bit=c
`define OC8051_MOV_DP 8'b1001_0000 // move dptr=constant(16 bit)
`define OC8051_MOVC_DP 8'b1001_0011 // move A=dptr+A
`define OC8051_MOVC_PC 8'b1000_0011 // move A=pc+A
`define OC8051_MOVX_PA 8'b1110_0000 // move A=(dptr)
`define OC8051_MOVX_AP 8'b1111_0000 // move (dptr)=A
`define OC8051_MUL 8'b1010_0100 // multiply a*b
`define OC8051_NOP 8'b0000_0000 // no operation
`define OC8051_ORL_D 8'b0100_0101 // or A=A or (direct)
`define OC8051_ORL_C 8'b0100_0100 // or A=A or constant
`define OC8051_ORL_AD 8'b0100_0010 // or (direct)=(direct) or A
`define OC8051_ORL_CD 8'b0100_0011 // or (direct)=(direct) or constant
`define OC8051_ORL_B 8'b0111_0010 // or c = c or bit
`define OC8051_ORL_NB 8'b1010_0000 // or c = c or !bit
`define OC8051_POP 8'b1101_0000 // stack pop
`define OC8051_PUSH 8'b1100_0000 // stack push
`define OC8051_RET 8'b0010_0010 // return from subrutine
`define OC8051_RETI 8'b0011_0010 // return from interrupt
`define OC8051_RL 8'b0010_0011 // rotate left
`define OC8051_RLC 8'b0011_0011 // rotate left thrugh carry
`define OC8051_RR 8'b0000_0011 // rotate right
`define OC8051_RRC 8'b0001_0011 // rotate right thrugh carry
`define OC8051_SETB_C 8'b1101_0011 // set carry
`define OC8051_SETB_B 8'b1101_0010 // set bit
`define OC8051_SJMP 8'b1000_0000 // short jump
`define OC8051_SUBB_D 8'b1001_0101 // substract with borrow A=A-c-(direct)
`define OC8051_SUBB_C 8'b1001_0100 // substract with borrow A=A-c-constant
`define OC8051_SWAP 8'b1100_0100 // swap A(0-3) <-> A(4-7)
`define OC8051_XCH_D 8'b1100_0101 // exchange A<->(direct)
`define OC8051_XRL_D 8'b0110_0101 // XOR A=A XOR (direct)
`define OC8051_XRL_C 8'b0110_0100 // XOR A=A XOR constant
`define OC8051_XRL_AD 8'b0110_0010 // XOR (direct)=(direct) XOR A
`define OC8051_XRL_CD 8'b0110_0011 // XOR (direct)=(direct) XOR constant
 
 
//
// default values (used after reset)
//
`define OC8051_RST_PC 23'h0 // program counter
`define OC8051_RST_ACC 8'h00 // accumulator
`define OC8051_RST_B 8'h00 // b register
`define OC8051_RST_PSW 8'h00 // program status word
`define OC8051_RST_SP 8'b0000_0111 // stack pointer
`define OC8051_RST_DPH 8'h00 // data pointer (high)
`define OC8051_RST_DPL 8'h00 // data pointer (low)
`define OC8051_RST_P0 8'b1111_1111 // port 0
`define OC8051_RST_P1 8'b1111_1111 // port 1
`define OC8051_RST_P2 8'b1111_1111 // port 2
`define OC8051_RST_P3 8'b1111_1111 // port 3
`define OC8051_RST_IP 8'b0000_0000 // interrupt priority
`define OC8051_RST_IE 8'b0000_0000 // interrupt enable
`define OC8051_RST_TMOD 8'b0000_0000 // timer/counter mode control
`define OC8051_RST_TCON 8'b0000_0000 // timer/counter control
`define OC8051_RST_TH0 8'b0000_0000 // timer/counter 0 high bits
`define OC8051_RST_TL0 8'b0000_0000 // timer/counter 0 low bits
`define OC8051_RST_TH1 8'b0000_0000 // timer/counter 1 high bits
`define OC8051_RST_TL1 8'b0000_0000 // timer/counter 1 low bits
`define OC8051_RST_SCON 8'b0000_0000 // serial control
`define OC8051_RST_SBUF 8'b0000_0000 // serial data buffer
`define OC8051_RST_PCON 8'b0000_0000 // power control register
 
 
 
`define OC8051_RST_RCAP2H 8'h00 // timer 2 capture high
`define OC8051_RST_RCAP2L 8'h00 // timer 2 capture low
 
`define OC8051_RST_T2CON 8'h00 // timer 2 control register
`define OC8051_RST_T2MOD 8'h00 // timer 2 mode control
`define OC8051_RST_TH2 8'h00 // timer 2 high
`define OC8051_RST_TL2 8'h00 // timer 2 low
 
 
//
// alu source 1 select
//
`define OC8051_AS1_RAM 3'b000 // RAM
`define OC8051_AS1_OP1 3'b111 //
`define OC8051_AS1_OP2 3'b001 //
`define OC8051_AS1_OP3 3'b010 //
`define OC8051_AS1_ACC 3'b011 // accumulator
`define OC8051_AS1_PCH 3'b100 //
`define OC8051_AS1_PCL 3'b101 //
`define OC8051_AS1_DC 3'b000 //
 
//
// alu source 2 select
//
`define OC8051_AS2_RAM 3'b00 // RAM
`define OC8051_AS2_ACC 3'b01 // accumulator
`define OC8051_AS2_ZERO 3'b10 // 8'h00
`define OC8051_AS2_OP2 3'b11 //
 
`define OC8051_AS2_DC 3'b00 //
 
//
// alu source 3 select
//
`define OC8051_AS3_DP 1'b0 // data pointer
`define OC8051_AS3_PC 1'b1 // program clunter
//`define OC8051_AS3_PCU 3'b101 // program clunter not registered
`define OC8051_AS3_DC 1'b0 //
 
 
//
//write sfr
//
`define OC8051_WRS_N 2'b00 //no
`define OC8051_WRS_ACC1 2'b01 // acc destination 1
`define OC8051_WRS_ACC2 2'b10 // acc destination 2
`define OC8051_WRS_DPTR 2'b11 // data pointer
 
 
//
// ram read select
//
 
`define OC8051_RRS_RN 3'b000 // registers
`define OC8051_RRS_I 3'b001 // indirect addressing (op2)
`define OC8051_RRS_D 3'b010 // direct addressing
`define OC8051_RRS_SP 3'b011 // stack pointer
 
`define OC8051_RRS_B 3'b100 // b register
`define OC8051_RRS_DPTR 3'b101 // data pointer
`define OC8051_RRS_PSW 3'b110 // program status word
`define OC8051_RRS_ACC 3'b111 // acc
 
`define OC8051_RRS_DC 3'b000 // don't c
 
//
// ram write select
//
 
`define OC8051_RWS_RN 3'b000 // registers
`define OC8051_RWS_D 3'b001 // direct addressing
`define OC8051_RWS_I 3'b010 // indirect addressing
`define OC8051_RWS_SP 3'b011 // stack pointer
`define OC8051_RWS_D3 3'b101 // direct address (op3)
`define OC8051_RWS_D1 3'b110 // direct address (op1)
`define OC8051_RWS_B 3'b111 // b register
`define OC8051_RWS_DC 3'b000 //
 
//
// pc in select
//
`define OC8051_PIS_DC 3'b000 // dont c
`define OC8051_PIS_AL 3'b000 // alu low
`define OC8051_PIS_AH 3'b001 // alu high
`define OC8051_PIS_SO1 3'b010 // relative address, op1
`define OC8051_PIS_SO2 3'b011 // relative address, op2
`define OC8051_PIS_I11 3'b100 // 11 bit immediate
`define OC8051_PIS_I16 3'b101 // 16 bit immediate
`define OC8051_PIS_ALU 3'b110 // alu destination {des2, des1}
 
//
// compare source select
//
`define OC8051_CSS_AZ 2'b00 // eq = accumulator == zero
`define OC8051_CSS_DES 2'b01 // eq = destination == zero
`define OC8051_CSS_CY 2'b10 // eq = cy
`define OC8051_CSS_BIT 2'b11 // eq = b_in
`define OC8051_CSS_DC 2'b01 // don't care
 
 
//
// pc Write
//
`define OC8051_PCW_N 1'b0 // not
`define OC8051_PCW_Y 1'b1 // yes
 
//
//psw set
//
`define OC8051_PS_NOT 2'b00 // DONT
`define OC8051_PS_CY 2'b01 // only carry
`define OC8051_PS_OV 2'b10 // carry and overflov
`define OC8051_PS_AC 2'b11 // carry, overflov an ac...
 
//
// rom address select
//
`define OC8051_RAS_PC 1'b0 // program counter
`define OC8051_RAS_DES 1'b1 // alu destination
 
////
//// write accumulator
////
//`define OC8051_WA_N 1'b0 // not
//`define OC8051_WA_Y 1'b1 // yes
 
 
//
//memory action select
//
`define OC8051_MAS_DPTR_R 3'b000 // read from external rom: acc=(dptr)
`define OC8051_MAS_DPTR_W 3'b001 // write to external rom: (dptr)=acc
`define OC8051_MAS_RI_R 3'b010 // read from external rom: acc=(Ri)
`define OC8051_MAS_RI_W 3'b011 // write to external rom: (Ri)=acc
`define OC8051_MAS_CODE 3'b100 // read from program memory
`define OC8051_MAS_NO 3'b111 // no action
 
 
////////////////////////////////////////////////////
 
//
// Timer/Counter modes
//
 
`define OC8051_MODE0 2'b00 // mode 0
`define OC8051_MODE1 2'b01 // mode 0
`define OC8051_MODE2 2'b10 // mode 0
`define OC8051_MODE3 2'b11 // mode 0
 
 
//
// Interrupt numbers (vectors)
//
 
`define OC8051_INT_X0 8'h03 // external interrupt 0
`define OC8051_INT_T0 8'h0b // T/C 0 owerflow interrupt
`define OC8051_INT_X1 8'h13 // external interrupt 1
`define OC8051_INT_T1 8'h1b // T/C 1 owerflow interrupt
`define OC8051_INT_UART 8'h23 // uart interrupt
`define OC8051_INT_T2 8'h2b // T/C 2 owerflow interrupt
 
 
//
// interrupt levels
//
 
`define OC8051_ILEV_L0 1'b0 // interrupt on level 0
`define OC8051_ILEV_L1 1'b1 // interrupt on level 1
 
//
// interrupt sources
//
`define OC8051_ISRC_NO 3'b000 // no interrupts
`define OC8051_ISRC_IE0 3'b001 // EXTERNAL INTERRUPT 0
`define OC8051_ISRC_TF0 3'b010 // t/c owerflov 0
`define OC8051_ISRC_IE1 3'b011 // EXTERNAL INTERRUPT 1
`define OC8051_ISRC_TF1 3'b100 // t/c owerflov 1
`define OC8051_ISRC_UART 3'b101 // UART Interrupt
`define OC8051_ISRC_T2 3'b110 // t/c owerflov 2
 
 
 
//
// miscellaneus
//
 
`define OC8051_RW0 1'b1
`define OC8051_RW1 1'b0
 
 
//
// read modify write instruction
//
 
`define OC8051_RMW_Y 1'b1 // yes
`define OC8051_RMW_N 1'b0 // no
 
//////////////////////////////////////////////////////////////////////
//// ////
//// 8051 cores Definitions ////
//// ////
//// This file is part of the 8051 cores project ////
//// http://www.opencores.org/cores/8051/ ////
//// ////
//// Description ////
//// 8051 definitions. ////
//// ////
//// To Do: ////
//// Nothing ////
//// ////
//// Author(s): ////
//// - Simon Teran, simont@opencores.org ////
//// - Jaka Simsic, jakas@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// ver: 1
//
 
//
// oc8051 pherypherals
//
//`define OC8051_UART
`define OC8051_TC01
`define OC8051_TC2
`define OC8051_PORTS //ports global enable
`define OC8051_PORT0
`define OC8051_PORT1
`define OC8051_PORT2
`define OC8051_PORT3
 
 
//
// oc8051 ITERNAL ROM
//
//`define OC8051_ROM
 
 
//
// oc8051 memory
//
//`define OC8051_CACHE
//`define OC8051_WB
 
//`define OC8051_RAM_XILINX
//`define OC8051_RAM_VIRTUALSILICON
//`define OC8051_RAM_GENERIC
 
//`define OC8051_RAM_ACTEL
 
//`define OC8051_XILINX_ROM
//`define OC8051_ACTEL_ROM
 
//
// oc8051 simulation defines
//
//`define OC8051_SIMULATION
//`define OC8051_SERIAL
 
//
// oc8051 bist
//
//`define OC8051_BIST
 
 
//
// operation codes for alu
//
 
 
`define OC8051_ALU_NOP 4'b0000
`define OC8051_ALU_ADD 4'b0001
`define OC8051_ALU_SUB 4'b0010
`define OC8051_ALU_MUL 4'b0011
`define OC8051_ALU_DIV 4'b0100
`define OC8051_ALU_DA 4'b0101
`define OC8051_ALU_NOT 4'b0110
`define OC8051_ALU_AND 4'b0111
`define OC8051_ALU_XOR 4'b1000
`define OC8051_ALU_OR 4'b1001
`define OC8051_ALU_RL 4'b1010
`define OC8051_ALU_RLC 4'b1011
`define OC8051_ALU_RR 4'b1100
`define OC8051_ALU_RRC 4'b1101
`define OC8051_ALU_INC 4'b1110
`define OC8051_ALU_XCH 4'b1111
 
//
// sfr addresses
//
 
`define OC8051_SFR_ACC 8'he0 //accumulator
`define OC8051_SFR_B 8'hf0 //b register
`define OC8051_SFR_PSW 8'hd0 //program status word
`define OC8051_SFR_P0 8'h80 //port 0
`define OC8051_SFR_P1 8'h90 //port 1
`define OC8051_SFR_P2 8'ha0 //port 2
`define OC8051_SFR_P3 8'hb0 //port 3
`define OC8051_SFR_DPTR_LO 8'h82 // data pointer high bits
`define OC8051_SFR_DPTR_HI 8'h83 // data pointer low bits
`define OC8051_SFR_IP0 8'hb8 // interrupt priority
`define OC8051_SFR_IEN0 8'ha8 // interrupt enable 0
`define OC8051_SFR_TMOD 8'h89 // timer/counter mode
`define OC8051_SFR_TCON 8'h88 // timer/counter control
`define OC8051_SFR_TH0 8'h8c // timer/counter 0 high bits
`define OC8051_SFR_TL0 8'h8a // timer/counter 0 low bits
`define OC8051_SFR_TH1 8'h8d // timer/counter 1 high bits
`define OC8051_SFR_TL1 8'h8b // timer/counter 1 low bits
 
`define OC8051_SFR_SCON 8'h98 // serial control 0
`define OC8051_SFR_SBUF 8'h99 // serial data buffer 0
`define OC8051_SFR_SADDR 8'ha9 // serila address register 0
`define OC8051_SFR_SADEN 8'hb9 // serila address enable 0
 
`define OC8051_SFR_PCON 8'h87 // power control
`define OC8051_SFR_SP 8'h81 // stack pointer
 
 
 
`define OC8051_SFR_IE 8'ha8 // interrupt enable
`define OC8051_SFR_IP 8'hb7 // interrupt priority
 
`define OC8051_SFR_RCAP2H 8'hcb // timer 2 capture high
`define OC8051_SFR_RCAP2L 8'hca // timer 2 capture low
 
`define OC8051_SFR_T2CON 8'hc8 // timer 2 control register
`define OC8051_SFR_TH2 8'hcd // timer 2 high
`define OC8051_SFR_TL2 8'hcc // timer 2 low
 
 
 
//
// sfr bit addresses
//
`define OC8051_SFR_B_ACC 5'b11100 //accumulator
`define OC8051_SFR_B_PSW 5'b11010 //program status word
`define OC8051_SFR_B_P0 5'b10000 //port 0
`define OC8051_SFR_B_P1 5'b10010 //port 1
`define OC8051_SFR_B_P2 5'b10100 //port 2
`define OC8051_SFR_B_P3 5'b10110 //port 3
`define OC8051_SFR_B_B 5'b11110 // b register
`define OC8051_SFR_B_IP 5'b10111 // interrupt priority control 0
`define OC8051_SFR_B_IE 5'b10101 // interrupt enable control 0
`define OC8051_SFR_B_SCON 5'b10011 // serial control
`define OC8051_SFR_B_TCON 5'b10001 // timer/counter control
`define OC8051_SFR_B_T2CON 5'b11001 // timer/counter2 control
 
 
//
//carry input in alu
//
`define OC8051_CY_0 2'b00 // 1'b0;
`define OC8051_CY_PSW 2'b01 // carry from psw
`define OC8051_CY_RAM 2'b10 // carry from ram
`define OC8051_CY_1 2'b11 // 1'b1;
`define OC8051_CY_DC 2'b00 // carry from psw
 
//
// instruction set
//
 
//op_code [4:0]
`define OC8051_ACALL 8'bxxx1_0001 // absolute call
`define OC8051_AJMP 8'bxxx0_0001 // absolute jump
 
//op_code [7:3]
`define OC8051_ADD_R 8'b0010_1xxx // add A=A+Rx
`define OC8051_ADDC_R 8'b0011_1xxx // add A=A+Rx+c
`define OC8051_ANL_R 8'b0101_1xxx // and A=A^Rx
`define OC8051_CJNE_R 8'b1011_1xxx // compare and jump if not equal; Rx<>constant
`define OC8051_DEC_R 8'b0001_1xxx // decrement reg Rn=Rn-1
`define OC8051_DJNZ_R 8'b1101_1xxx // decrement and jump if not zero
`define OC8051_INC_R 8'b0000_1xxx // increment Rn
`define OC8051_MOV_R 8'b1110_1xxx // move A=Rn
`define OC8051_MOV_AR 8'b1111_1xxx // move Rn=A
`define OC8051_MOV_DR 8'b1010_1xxx // move Rn=(direct)
`define OC8051_MOV_CR 8'b0111_1xxx // move Rn=constant
`define OC8051_MOV_RD 8'b1000_1xxx // move (direct)=Rn
`define OC8051_ORL_R 8'b0100_1xxx // or A=A or Rn
`define OC8051_SUBB_R 8'b1001_1xxx // substract with borrow A=A-c-Rn
`define OC8051_XCH_R 8'b1100_1xxx // exchange A<->Rn
`define OC8051_XRL_R 8'b0110_1xxx // XOR A=A XOR Rn
 
//op_code [7:1]
`define OC8051_ADD_I 8'b0010_011x // add A=A+@Ri
`define OC8051_ADDC_I 8'b0011_011x // add A=A+@Ri+c
`define OC8051_ANL_I 8'b0101_011x // and A=A^@Ri
`define OC8051_CJNE_I 8'b1011_011x // compare and jump if not equal; @Ri<>constant
`define OC8051_DEC_I 8'b0001_011x // decrement indirect @Ri=@Ri-1
`define OC8051_INC_I 8'b0000_011x // increment @Ri
`define OC8051_MOV_I 8'b1110_011x // move A=@Ri
`define OC8051_MOV_ID 8'b1000_011x // move (direct)=@Ri
`define OC8051_MOV_AI 8'b1111_011x // move @Ri=A
`define OC8051_MOV_DI 8'b1010_011x // move @Ri=(direct)
`define OC8051_MOV_CI 8'b0111_011x // move @Ri=constant
`define OC8051_MOVX_IA 8'b1110_001x // move A=(@Ri)
`define OC8051_MOVX_AI 8'b1111_001x // move (@Ri)=A
`define OC8051_ORL_I 8'b0100_011x // or A=A or @Ri
`define OC8051_SUBB_I 8'b1001_011x // substract with borrow A=A-c-@Ri
`define OC8051_XCH_I 8'b1100_011x // exchange A<->@Ri
`define OC8051_XCHD 8'b1101_011x // exchange digit A<->Ri
`define OC8051_XRL_I 8'b0110_011x // XOR A=A XOR @Ri
 
//op_code [7:0]
`define OC8051_ADD_D 8'b0010_0101 // add A=A+(direct)
`define OC8051_ADD_C 8'b0010_0100 // add A=A+constant
`define OC8051_ADDC_D 8'b0011_0101 // add A=A+(direct)+c
`define OC8051_ADDC_C 8'b0011_0100 // add A=A+constant+c
`define OC8051_ANL_D 8'b0101_0101 // and A=A^(direct)
`define OC8051_ANL_C 8'b0101_0100 // and A=A^constant
`define OC8051_ANL_DD 8'b0101_0010 // and (direct)=(direct)^A
`define OC8051_ANL_DC 8'b0101_0011 // and (direct)=(direct)^constant
`define OC8051_ANL_B 8'b1000_0010 // and c=c^bit
`define OC8051_ANL_NB 8'b1011_0000 // and c=c^!bit
`define OC8051_CJNE_D 8'b1011_0101 // compare and jump if not equal; a<>(direct)
`define OC8051_CJNE_C 8'b1011_0100 // compare and jump if not equal; a<>constant
`define OC8051_CLR_A 8'b1110_0100 // clear accumulator
`define OC8051_CLR_C 8'b1100_0011 // clear carry
`define OC8051_CLR_B 8'b1100_0010 // clear bit
`define OC8051_CPL_A 8'b1111_0100 // complement accumulator
`define OC8051_CPL_C 8'b1011_0011 // complement carry
`define OC8051_CPL_B 8'b1011_0010 // complement bit
`define OC8051_DA 8'b1101_0100 // decimal adjust (A)
`define OC8051_DEC_A 8'b0001_0100 // decrement accumulator a=a-1
`define OC8051_DEC_D 8'b0001_0101 // decrement direct (direct)=(direct)-1
`define OC8051_DIV 8'b1000_0100 // divide
`define OC8051_DJNZ_D 8'b1101_0101 // decrement and jump if not zero (direct)
`define OC8051_INC_A 8'b0000_0100 // increment accumulator
`define OC8051_INC_D 8'b0000_0101 // increment (direct)
`define OC8051_INC_DP 8'b1010_0011 // increment data pointer
`define OC8051_JB 8'b0010_0000 // jump if bit set
`define OC8051_JBC 8'b0001_0000 // jump if bit set and clear bit
`define OC8051_JC 8'b0100_0000 // jump if carry is set
`define OC8051_JMP_D 8'b0111_0011 // jump indirect
`define OC8051_JNB 8'b0011_0000 // jump if bit not set
`define OC8051_JNC 8'b0101_0000 // jump if carry not set
`define OC8051_JNZ 8'b0111_0000 // jump if accumulator not zero
`define OC8051_JZ 8'b0110_0000 // jump if accumulator zero
`define OC8051_LCALL 8'b0001_0010 // long call
`define OC8051_LJMP 8'b0000_0010 // long jump
`define OC8051_MOV_D 8'b1110_0101 // move A=(direct)
`define OC8051_MOV_C 8'b0111_0100 // move A=constant
`define OC8051_MOV_DA 8'b1111_0101 // move (direct)=A
`define OC8051_MOV_DD 8'b1000_0101 // move (direct)=(direct)
`define OC8051_MOV_CD 8'b0111_0101 // move (direct)=constant
`define OC8051_MOV_BC 8'b1010_0010 // move c=bit
`define OC8051_MOV_CB 8'b1001_0010 // move bit=c
`define OC8051_MOV_DP 8'b1001_0000 // move dptr=constant(16 bit)
`define OC8051_MOVC_DP 8'b1001_0011 // move A=dptr+A
`define OC8051_MOVC_PC 8'b1000_0011 // move A=pc+A
`define OC8051_MOVX_PA 8'b1110_0000 // move A=(dptr)
`define OC8051_MOVX_AP 8'b1111_0000 // move (dptr)=A
`define OC8051_MUL 8'b1010_0100 // multiply a*b
`define OC8051_NOP 8'b0000_0000 // no operation
`define OC8051_ORL_D 8'b0100_0101 // or A=A or (direct)
`define OC8051_ORL_C 8'b0100_0100 // or A=A or constant
`define OC8051_ORL_AD 8'b0100_0010 // or (direct)=(direct) or A
`define OC8051_ORL_CD 8'b0100_0011 // or (direct)=(direct) or constant
`define OC8051_ORL_B 8'b0111_0010 // or c = c or bit
`define OC8051_ORL_NB 8'b1010_0000 // or c = c or !bit
`define OC8051_POP 8'b1101_0000 // stack pop
`define OC8051_PUSH 8'b1100_0000 // stack push
`define OC8051_RET 8'b0010_0010 // return from subrutine
`define OC8051_RETI 8'b0011_0010 // return from interrupt
`define OC8051_RL 8'b0010_0011 // rotate left
`define OC8051_RLC 8'b0011_0011 // rotate left thrugh carry
`define OC8051_RR 8'b0000_0011 // rotate right
`define OC8051_RRC 8'b0001_0011 // rotate right thrugh carry
`define OC8051_SETB_C 8'b1101_0011 // set carry
`define OC8051_SETB_B 8'b1101_0010 // set bit
`define OC8051_SJMP 8'b1000_0000 // short jump
`define OC8051_SUBB_D 8'b1001_0101 // substract with borrow A=A-c-(direct)
`define OC8051_SUBB_C 8'b1001_0100 // substract with borrow A=A-c-constant
`define OC8051_SWAP 8'b1100_0100 // swap A(0-3) <-> A(4-7)
`define OC8051_XCH_D 8'b1100_0101 // exchange A<->(direct)
`define OC8051_XRL_D 8'b0110_0101 // XOR A=A XOR (direct)
`define OC8051_XRL_C 8'b0110_0100 // XOR A=A XOR constant
`define OC8051_XRL_AD 8'b0110_0010 // XOR (direct)=(direct) XOR A
`define OC8051_XRL_CD 8'b0110_0011 // XOR (direct)=(direct) XOR constant
 
 
//
// default values (used after reset)
//
`define OC8051_RST_PC 23'h0 // program counter
`define OC8051_RST_ACC 8'h00 // accumulator
`define OC8051_RST_B 8'h00 // b register
`define OC8051_RST_PSW 8'h00 // program status word
`define OC8051_RST_SP 8'b0000_0111 // stack pointer
`define OC8051_RST_DPH 8'h00 // data pointer (high)
`define OC8051_RST_DPL 8'h00 // data pointer (low)
`define OC8051_RST_P0 8'b1111_1111 // port 0
`define OC8051_RST_P1 8'b1111_1111 // port 1
`define OC8051_RST_P2 8'b1111_1111 // port 2
`define OC8051_RST_P3 8'b1111_1111 // port 3
`define OC8051_RST_IP 8'b0000_0000 // interrupt priority
`define OC8051_RST_IE 8'b0000_0000 // interrupt enable
`define OC8051_RST_TMOD 8'b0000_0000 // timer/counter mode control
`define OC8051_RST_TCON 8'b0000_0000 // timer/counter control
`define OC8051_RST_TH0 8'b0000_0000 // timer/counter 0 high bits
`define OC8051_RST_TL0 8'b0000_0000 // timer/counter 0 low bits
`define OC8051_RST_TH1 8'b0000_0000 // timer/counter 1 high bits
`define OC8051_RST_TL1 8'b0000_0000 // timer/counter 1 low bits
`define OC8051_RST_SCON 8'b0000_0000 // serial control
`define OC8051_RST_SBUF 8'b0000_0000 // serial data buffer
`define OC8051_RST_PCON 8'b0000_0000 // power control register
 
 
 
`define OC8051_RST_RCAP2H 8'h00 // timer 2 capture high
`define OC8051_RST_RCAP2L 8'h00 // timer 2 capture low
 
`define OC8051_RST_T2CON 8'h00 // timer 2 control register
`define OC8051_RST_T2MOD 8'h00 // timer 2 mode control
`define OC8051_RST_TH2 8'h00 // timer 2 high
`define OC8051_RST_TL2 8'h00 // timer 2 low
 
 
//
// alu source 1 select
//
`define OC8051_AS1_RAM 3'b000 // RAM
`define OC8051_AS1_OP1 3'b111 //
`define OC8051_AS1_OP2 3'b001 //
`define OC8051_AS1_OP3 3'b010 //
`define OC8051_AS1_ACC 3'b011 // accumulator
`define OC8051_AS1_PCH 3'b100 //
`define OC8051_AS1_PCL 3'b101 //
`define OC8051_AS1_DC 3'b000 //
 
//
// alu source 2 select
//
`define OC8051_AS2_RAM 3'b00 // RAM
`define OC8051_AS2_ACC 3'b01 // accumulator
`define OC8051_AS2_ZERO 3'b10 // 8'h00
`define OC8051_AS2_OP2 3'b11 //
 
`define OC8051_AS2_DC 3'b00 //
 
//
// alu source 3 select
//
`define OC8051_AS3_DP 1'b0 // data pointer
`define OC8051_AS3_PC 1'b1 // program clunter
//`define OC8051_AS3_PCU 3'b101 // program clunter not registered
`define OC8051_AS3_DC 1'b0 //
 
 
//
//write sfr
//
`define OC8051_WRS_N 2'b00 //no
`define OC8051_WRS_ACC1 2'b01 // acc destination 1
`define OC8051_WRS_ACC2 2'b10 // acc destination 2
`define OC8051_WRS_DPTR 2'b11 // data pointer
 
 
//
// ram read select
//
 
`define OC8051_RRS_RN 3'b000 // registers
`define OC8051_RRS_I 3'b001 // indirect addressing (op2)
`define OC8051_RRS_D 3'b010 // direct addressing
`define OC8051_RRS_SP 3'b011 // stack pointer
 
`define OC8051_RRS_B 3'b100 // b register
`define OC8051_RRS_DPTR 3'b101 // data pointer
`define OC8051_RRS_PSW 3'b110 // program status word
`define OC8051_RRS_ACC 3'b111 // acc
 
`define OC8051_RRS_DC 3'b000 // don't c
 
//
// ram write select
//
 
`define OC8051_RWS_RN 3'b000 // registers
`define OC8051_RWS_D 3'b001 // direct addressing
`define OC8051_RWS_I 3'b010 // indirect addressing
`define OC8051_RWS_SP 3'b011 // stack pointer
`define OC8051_RWS_D3 3'b101 // direct address (op3)
`define OC8051_RWS_D1 3'b110 // direct address (op1)
`define OC8051_RWS_B 3'b111 // b register
`define OC8051_RWS_DC 3'b000 //
 
//
// pc in select
//
`define OC8051_PIS_DC 3'b000 // dont c
`define OC8051_PIS_AL 3'b000 // alu low
`define OC8051_PIS_AH 3'b001 // alu high
`define OC8051_PIS_SO1 3'b010 // relative address, op1
`define OC8051_PIS_SO2 3'b011 // relative address, op2
`define OC8051_PIS_I11 3'b100 // 11 bit immediate
`define OC8051_PIS_I16 3'b101 // 16 bit immediate
`define OC8051_PIS_ALU 3'b110 // alu destination {des2, des1}
 
//
// compare source select
//
`define OC8051_CSS_AZ 2'b00 // eq = accumulator == zero
`define OC8051_CSS_DES 2'b01 // eq = destination == zero
`define OC8051_CSS_CY 2'b10 // eq = cy
`define OC8051_CSS_BIT 2'b11 // eq = b_in
`define OC8051_CSS_DC 2'b01 // don't care
 
 
//
// pc Write
//
`define OC8051_PCW_N 1'b0 // not
`define OC8051_PCW_Y 1'b1 // yes
 
//
//psw set
//
`define OC8051_PS_NOT 2'b00 // DONT
`define OC8051_PS_CY 2'b01 // only carry
`define OC8051_PS_OV 2'b10 // carry and overflov
`define OC8051_PS_AC 2'b11 // carry, overflov an ac...
 
//
// rom address select
//
`define OC8051_RAS_PC 1'b0 // program counter
`define OC8051_RAS_DES 1'b1 // alu destination
 
////
//// write accumulator
////
//`define OC8051_WA_N 1'b0 // not
//`define OC8051_WA_Y 1'b1 // yes
 
 
//
//memory action select
//
`define OC8051_MAS_DPTR_R 3'b000 // read from external rom: acc=(dptr)
`define OC8051_MAS_DPTR_W 3'b001 // write to external rom: (dptr)=acc
`define OC8051_MAS_RI_R 3'b010 // read from external rom: acc=(Ri)
`define OC8051_MAS_RI_W 3'b011 // write to external rom: (Ri)=acc
`define OC8051_MAS_CODE 3'b100 // read from program memory
`define OC8051_MAS_NO 3'b111 // no action
 
 
////////////////////////////////////////////////////
 
//
// Timer/Counter modes
//
 
`define OC8051_MODE0 2'b00 // mode 0
`define OC8051_MODE1 2'b01 // mode 0
`define OC8051_MODE2 2'b10 // mode 0
`define OC8051_MODE3 2'b11 // mode 0
 
 
//
// Interrupt numbers (vectors)
//
 
`define OC8051_INT_X0 8'h03 // external interrupt 0
`define OC8051_INT_T0 8'h0b // T/C 0 owerflow interrupt
`define OC8051_INT_X1 8'h13 // external interrupt 1
`define OC8051_INT_T1 8'h1b // T/C 1 owerflow interrupt
`define OC8051_INT_UART 8'h23 // uart interrupt
`define OC8051_INT_T2 8'h2b // T/C 2 owerflow interrupt
 
 
//
// interrupt levels
//
 
`define OC8051_ILEV_L0 1'b0 // interrupt on level 0
`define OC8051_ILEV_L1 1'b1 // interrupt on level 1
 
//
// interrupt sources
//
`define OC8051_ISRC_NO 3'b000 // no interrupts
`define OC8051_ISRC_IE0 3'b001 // EXTERNAL INTERRUPT 0
`define OC8051_ISRC_TF0 3'b010 // t/c owerflov 0
`define OC8051_ISRC_IE1 3'b011 // EXTERNAL INTERRUPT 1
`define OC8051_ISRC_TF1 3'b100 // t/c owerflov 1
`define OC8051_ISRC_UART 3'b101 // UART Interrupt
`define OC8051_ISRC_T2 3'b110 // t/c owerflov 2
 
 
 
//
// miscellaneus
//
 
`define OC8051_RW0 1'b1
`define OC8051_RW1 1'b0
 
 
//
// read modify write instruction
//
 
`define OC8051_RMW_Y 1'b1 // yes
`define OC8051_RMW_N 1'b0 // no
/turbo8051/trunk/rtl/8051/oc8051_alu.v
1,410 → 1,418
//////////////////////////////////////////////////////////////////////
//// ////
//// alu for 8051 Core ////
//// ////
//// This file is part of the 8051 cores project ////
//// http://www.opencores.org/cores/8051/ ////
//// ////
//// Description ////
//// Implementation of aritmetic unit according to ////
//// 8051 IP core specification document. Uses divide.v and ////
//// multiply.v ////
//// ////
//// To Do: ////
//// pc signed add ////
//// ////
//// Author(s): ////
//// - Simon Teran, simont@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.18 2003/07/01 18:51:11 simont
// x replaced with 0.
//
// Revision 1.17 2003/06/09 16:51:16 simont
// fix bug in DA operation.
//
// Revision 1.16 2003/06/03 17:15:06 simont
// sub_result output added.
//
// Revision 1.15 2003/05/07 12:31:53 simont
// add wire sub_result, conect it to des_acc and des1.
//
// Revision 1.14 2003/05/05 15:46:36 simont
// add aditional alu destination to solve critical path.
//
// Revision 1.13 2003/04/29 08:35:12 simont
// fix bug in substraction.
//
// Revision 1.12 2003/04/25 17:15:51 simont
// change branch instruction execution (reduse needed clock periods).
//
// Revision 1.11 2003/04/14 14:29:42 simont
// fiz bug iv pcs operation.
//
// Revision 1.10 2003/01/13 14:14:40 simont
// replace some modules
//
// Revision 1.9 2002/09/30 17:33:59 simont
// prepared header
//
//
 
// synopsys translate_off
`include "oc8051_timescale.v"
// synopsys translate_on
 
`include "oc8051_defines.v"
 
 
 
module oc8051_alu (clk, rst, op_code, src1, src2, src3, srcCy, srcAc, bit_in,
des1, des2, des_acc, desCy, desAc, desOv, sub_result);
//
// op_code (in) operation code [oc8051_decoder.alu_op -r]
// src1 (in) first operand [oc8051_alu_src1_sel.des]
// src2 (in) second operand [oc8051_alu_src2_sel.des]
// src3 (in) third operand [oc8051_alu_src3_sel.des]
// srcCy (in) carry input [oc8051_cy_select.data_out]
// srcAc (in) auxiliary carry input [oc8051_psw.data_out[6] ]
// bit_in (in) bit input, used for logic operatins on bits [oc8051_ram_sel.bit_out]
// des1 (out)
// des2 (out)
// desCy (out) carry output [oc8051_ram_top.bit_data_in, oc8051_acc.bit_in, oc8051_b_register.bit_in, oc8051_psw.cy_in, oc8051_ports.bit_in]
// desAc (out) auxiliary carry output [oc8051_psw.ac_in]
// desOv (out) Overflow output [oc8051_psw.ov_in]
//
 
input srcCy, srcAc, bit_in, clk, rst;
input [3:0] op_code;
input [7:0] src1, src2, src3;
output desCy, desAc, desOv;
output [7:0] des1, des2, des_acc, sub_result;
 
reg desCy, desAc, desOv;
reg [7:0] des1, des2, des_acc;
 
 
//
//add
//
wire [4:0] add1, add2, add3, add4;
wire [3:0] add5, add6, add7, add8;
wire [1:0] add9, adda, addb, addc;
 
//
//sub
//
wire [4:0] sub1, sub2, sub3, sub4;
wire [3:0] sub5, sub6, sub7, sub8;
wire [1:0] sub9, suba, subb, subc;
wire [7:0] sub_result;
 
//
//mul
//
wire [7:0] mulsrc1, mulsrc2;
wire mulOv;
reg enable_mul;
 
//
//div
//
wire [7:0] divsrc1,divsrc2;
wire divOv;
reg enable_div;
 
//
//da
//
reg da_tmp, da_tmp1;
//reg [8:0] da1;
 
//
// inc
//
wire [15:0] inc, dec;
 
oc8051_multiply oc8051_mul1(.clk(clk), .rst(rst), .enable(enable_mul), .src1(src1), .src2(src2), .des1(mulsrc1), .des2(mulsrc2), .desOv(mulOv));
oc8051_divide oc8051_div1(.clk(clk), .rst(rst), .enable(enable_div), .src1(src1), .src2(src2), .des1(divsrc1), .des2(divsrc2), .desOv(divOv));
 
/* Add */
assign add1 = {1'b0,src1[3:0]};
assign add2 = {1'b0,src2[3:0]};
assign add3 = {3'b000,srcCy};
assign add4 = add1+add2+add3;
 
assign add5 = {1'b0,src1[6:4]};
assign add6 = {1'b0,src2[6:4]};
assign add7 = {1'b0,1'b0,1'b0,add4[4]};
assign add8 = add5+add6+add7;
 
assign add9 = {1'b0,src1[7]};
assign adda = {1'b0,src2[7]};
assign addb = {1'b0,add8[3]};
assign addc = add9+adda+addb;
 
/* Sub */
assign sub1 = {1'b1,src1[3:0]};
assign sub2 = {1'b0,src2[3:0]};
assign sub3 = {1'b0,1'b0,1'b0,srcCy};
assign sub4 = sub1-sub2-sub3;
 
assign sub5 = {1'b1,src1[6:4]};
assign sub6 = {1'b0,src2[6:4]};
assign sub7 = {1'b0,1'b0,1'b0, !sub4[4]};
assign sub8 = sub5-sub6-sub7;
 
assign sub9 = {1'b1,src1[7]};
assign suba = {1'b0,src2[7]};
assign subb = {1'b0,!sub8[3]};
assign subc = sub9-suba-subb;
 
assign sub_result = {subc[0],sub8[2:0],sub4[3:0]};
 
/* inc */
assign inc = {src2, src1} + {15'h0, 1'b1};
assign dec = {src2, src1} - {15'h0, 1'b1};
 
always @(op_code or src1 or src2 or srcCy or srcAc or bit_in or src3 or mulsrc1
or mulsrc2 or mulOv or divsrc1 or divsrc2 or divOv or addc or add8 or add4
or sub4 or sub8 or subc or da_tmp or inc or dec or sub_result)
begin
 
case (op_code) /* synopsys full_case parallel_case */
//operation add
`OC8051_ALU_ADD: begin
des_acc = {addc[0],add8[2:0],add4[3:0]};
des1 = src1;
des2 = src3+ {7'b0, addc[1]};
desCy = addc[1];
desAc = add4[4];
desOv = addc[1] ^ add8[3];
 
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation subtract
`OC8051_ALU_SUB: begin
des_acc = sub_result;
// des1 = sub_result;
des1 = 8'h00;
des2 = 8'h00;
desCy = !subc[1];
desAc = !sub4[4];
desOv = !subc[1] ^ !sub8[3];
 
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation multiply
`OC8051_ALU_MUL: begin
des_acc = mulsrc1;
des1 = src1;
des2 = mulsrc2;
desOv = mulOv;
desCy = 1'b0;
desAc = 1'b0;
enable_mul = 1'b1;
enable_div = 1'b0;
end
//operation divide
`OC8051_ALU_DIV: begin
des_acc = divsrc1;
des1 = src1;
des2 = divsrc2;
desOv = divOv;
desAc = 1'b0;
desCy = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b1;
end
//operation decimal adjustment
`OC8051_ALU_DA: begin
 
if (srcAc==1'b1 | src1[3:0]>4'b1001) {da_tmp, des_acc[3:0]} = {1'b0, src1[3:0]}+ 5'b00110;
else {da_tmp, des_acc[3:0]} = {1'b0, src1[3:0]};
 
if (srcCy | da_tmp | src1[7:4]>4'b1001)
{da_tmp1, des_acc[7:4]} = {srcCy, src1[7:4]}+ 5'b00110 + {4'b0, da_tmp};
else {da_tmp1, des_acc[7:4]} = {srcCy, src1[7:4]} + {4'b0, da_tmp};
 
desCy = da_tmp | da_tmp1;
des1 = src1;
des2 = 8'h00;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation not
// bit operation not
`OC8051_ALU_NOT: begin
des_acc = ~src1;
des1 = ~src1;
des2 = 8'h00;
desCy = !srcCy;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation and
//bit operation and
`OC8051_ALU_AND: begin
des_acc = src1 & src2;
des1 = src1 & src2;
des2 = 8'h00;
desCy = srcCy & bit_in;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation xor
// bit operation xor
`OC8051_ALU_XOR: begin
des_acc = src1 ^ src2;
des1 = src1 ^ src2;
des2 = 8'h00;
desCy = srcCy ^ bit_in;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation or
// bit operation or
`OC8051_ALU_OR: begin
des_acc = src1 | src2;
des1 = src1 | src2;
des2 = 8'h00;
desCy = srcCy | bit_in;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation rotate left
// bit operation cy= cy or (not ram)
`OC8051_ALU_RL: begin
des_acc = {src1[6:0], src1[7]};
des1 = src1 ;
des2 = 8'h00;
desCy = srcCy | !bit_in;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation rotate left with carry and swap nibbles
`OC8051_ALU_RLC: begin
des_acc = {src1[6:0], srcCy};
des1 = src1 ;
des2 = {src1[3:0], src1[7:4]};
desCy = src1[7];
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation rotate right
`OC8051_ALU_RR: begin
des_acc = {src1[0], src1[7:1]};
des1 = src1 ;
des2 = 8'h00;
desCy = srcCy & !bit_in;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation rotate right with carry
`OC8051_ALU_RRC: begin
des_acc = {srcCy, src1[7:1]};
des1 = src1 ;
des2 = 8'h00;
desCy = src1[0];
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation pcs Add
`OC8051_ALU_INC: begin
if (srcCy) begin
des_acc = dec[7:0];
des1 = dec[7:0];
des2 = dec[15:8];
end else begin
des_acc = inc[7:0];
des1 = inc[7:0];
des2 = inc[15:8];
end
desCy = 1'b0;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation exchange
//if carry = 0 exchange low order digit
`OC8051_ALU_XCH: begin
if (srcCy)
begin
des_acc = src2;
des1 = src2;
des2 = src1;
end else begin
des_acc = {src1[7:4],src2[3:0]};
des1 = {src1[7:4],src2[3:0]};
des2 = {src2[7:4],src1[3:0]};
end
desCy = 1'b0;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
`OC8051_ALU_NOP: begin
des_acc = src1;
des1 = src1;
des2 = src2;
desCy = srcCy;
desAc = srcAc;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
endcase
end
 
endmodule
//////////////////////////////////////////////////////////////////////
//// ////
//// alu for 8051 Core ////
//// ////
//// This file is part of the 8051 cores project ////
//// http://www.opencores.org/cores/8051/ ////
//// ////
//// Description ////
//// Implementation of aritmetic unit according to ////
//// 8051 IP core specification document. Uses divide.v and ////
//// multiply.v ////
//// ////
//// To Do: ////
//// pc signed add ////
//// ////
//// Author(s): ////
//// - Simon Teran, simont@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.18 2003/07/01 18:51:11 simont
// x replaced with 0.
//
// Revision 1.17 2003/06/09 16:51:16 simont
// fix bug in DA operation.
//
// Revision 1.16 2003/06/03 17:15:06 simont
// sub_result output added.
//
// Revision 1.15 2003/05/07 12:31:53 simont
// add wire sub_result, conect it to des_acc and des1.
//
// Revision 1.14 2003/05/05 15:46:36 simont
// add aditional alu destination to solve critical path.
//
// Revision 1.13 2003/04/29 08:35:12 simont
// fix bug in substraction.
//
// Revision 1.12 2003/04/25 17:15:51 simont
// change branch instruction execution (reduse needed clock periods).
//
// Revision 1.11 2003/04/14 14:29:42 simont
// fiz bug iv pcs operation.
//
// Revision 1.10 2003/01/13 14:14:40 simont
// replace some modules
//
// Revision 1.9 2002/09/30 17:33:59 simont
// prepared header
//
//
 
// synopsys translate_off
`include "oc8051_timescale.v"
// synopsys translate_on
 
`include "oc8051_defines.v"
 
 
 
module oc8051_alu (clk, rst, op_code, src1, src2, src3, srcCy, srcAc, bit_in,
des1, des2, des_acc, desCy, desAc, desOv, sub_result);
//
// op_code (in) operation code [oc8051_decoder.alu_op -r]
// src1 (in) first operand [oc8051_alu_src1_sel.des]
// src2 (in) second operand [oc8051_alu_src2_sel.des]
// src3 (in) third operand [oc8051_alu_src3_sel.des]
// srcCy (in) carry input [oc8051_cy_select.data_out]
// srcAc (in) auxiliary carry input [oc8051_psw.data_out[6] ]
// bit_in (in) bit input, used for logic operatins on bits [oc8051_ram_sel.bit_out]
// des1 (out)
// des2 (out)
// desCy (out) carry output [oc8051_ram_top.bit_data_in, oc8051_acc.bit_in, oc8051_b_register.bit_in, oc8051_psw.cy_in, oc8051_ports.bit_in]
// desAc (out) auxiliary carry output [oc8051_psw.ac_in]
// desOv (out) Overflow output [oc8051_psw.ov_in]
//
 
input srcCy, srcAc, bit_in, clk, rst;
input [3:0] op_code;
input [7:0] src1, src2, src3;
output desCy, desAc, desOv;
output [7:0] des1, des2, des_acc, sub_result;
 
reg desCy, desAc, desOv;
reg [7:0] des1, des2, des_acc;
 
 
//
//add
//
wire [4:0] add1, add2, add3, add4;
wire [3:0] add5, add6, add7, add8;
wire [1:0] add9, adda, addb, addc;
 
//
//sub
//
wire [4:0] sub1, sub2, sub3, sub4;
wire [3:0] sub5, sub6, sub7, sub8;
wire [1:0] sub9, suba, subb, subc;
wire [7:0] sub_result;
 
//
//mul
//
wire [7:0] mulsrc1, mulsrc2;
wire mulOv;
reg enable_mul;
 
//
//div
//
wire [7:0] divsrc1,divsrc2;
wire divOv;
reg enable_div;
 
//
//da
//
reg da_tmp, da_tmp1;
//reg [8:0] da1;
 
//
// inc
//
wire [15:0] inc, dec;
 
 
oc8051_multiply oc8051_mul1(.clk(clk), .rst(rst), .enable(enable_mul), .src1(src1), .src2(src2), .des1(mulsrc1), .des2(mulsrc2), .desOv(mulOv));
 
 
 
 
 
 
 
oc8051_divide oc8051_div1(.clk(clk), .rst(rst), .enable(enable_div), .src1(src1), .src2(src2), .des1(divsrc1), .des2(divsrc2), .desOv(divOv));
 
/* Add */
assign add1 = {1'b0,src1[3:0]};
assign add2 = {1'b0,src2[3:0]};
assign add3 = {3'b000,srcCy};
assign add4 = add1+add2+add3;
 
assign add5 = {1'b0,src1[6:4]};
assign add6 = {1'b0,src2[6:4]};
assign add7 = {1'b0,1'b0,1'b0,add4[4]};
assign add8 = add5+add6+add7;
 
assign add9 = {1'b0,src1[7]};
assign adda = {1'b0,src2[7]};
assign addb = {1'b0,add8[3]};
assign addc = add9+adda+addb;
 
/* Sub */
assign sub1 = {1'b1,src1[3:0]};
assign sub2 = {1'b0,src2[3:0]};
assign sub3 = {1'b0,1'b0,1'b0,srcCy};
assign sub4 = sub1-sub2-sub3;
 
assign sub5 = {1'b1,src1[6:4]};
assign sub6 = {1'b0,src2[6:4]};
assign sub7 = {1'b0,1'b0,1'b0, !sub4[4]};
assign sub8 = sub5-sub6-sub7;
 
assign sub9 = {1'b1,src1[7]};
assign suba = {1'b0,src2[7]};
assign subb = {1'b0,!sub8[3]};
assign subc = sub9-suba-subb;
 
assign sub_result = {subc[0],sub8[2:0],sub4[3:0]};
 
/* inc */
assign inc = {src2, src1} + {15'h0, 1'b1};
assign dec = {src2, src1} - {15'h0, 1'b1};
 
always @(op_code or src1 or src2 or srcCy or srcAc or bit_in or src3 or mulsrc1
or mulsrc2 or mulOv or divsrc1 or divsrc2 or divOv or addc or add8 or add4
or sub4 or sub8 or subc or da_tmp or inc or dec or sub_result)
begin
 
case (op_code) /* synopsys full_case parallel_case */
//operation add
`OC8051_ALU_ADD: begin
des_acc = {addc[0],add8[2:0],add4[3:0]};
des1 = src1;
des2 = src3+ {7'b0, addc[1]};
desCy = addc[1];
desAc = add4[4];
desOv = addc[1] ^ add8[3];
 
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation subtract
`OC8051_ALU_SUB: begin
des_acc = sub_result;
// des1 = sub_result;
des1 = 8'h00;
des2 = 8'h00;
desCy = !subc[1];
desAc = !sub4[4];
desOv = !subc[1] ^ !sub8[3];
 
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation multiply
`OC8051_ALU_MUL: begin
des_acc = mulsrc1;
des1 = src1;
des2 = mulsrc2;
desOv = mulOv;
desCy = 1'b0;
desAc = 1'b0;
enable_mul = 1'b1;
enable_div = 1'b0;
end
//operation divide
`OC8051_ALU_DIV: begin
des_acc = divsrc1;
des1 = src1;
des2 = divsrc2;
desOv = divOv;
desAc = 1'b0;
desCy = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b1;
end
//operation decimal adjustment
`OC8051_ALU_DA: begin
 
if (srcAc==1'b1 | src1[3:0]>4'b1001) {da_tmp, des_acc[3:0]} = {1'b0, src1[3:0]}+ 5'b00110;
else {da_tmp, des_acc[3:0]} = {1'b0, src1[3:0]};
 
if (srcCy | da_tmp | src1[7:4]>4'b1001)
{da_tmp1, des_acc[7:4]} = {srcCy, src1[7:4]}+ 5'b00110 + {4'b0, da_tmp};
else {da_tmp1, des_acc[7:4]} = {srcCy, src1[7:4]} + {4'b0, da_tmp};
 
desCy = da_tmp | da_tmp1;
des1 = src1;
des2 = 8'h00;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation not
// bit operation not
`OC8051_ALU_NOT: begin
des_acc = ~src1;
des1 = ~src1;
des2 = 8'h00;
desCy = !srcCy;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation and
//bit operation and
`OC8051_ALU_AND: begin
des_acc = src1 & src2;
des1 = src1 & src2;
des2 = 8'h00;
desCy = srcCy & bit_in;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation xor
// bit operation xor
`OC8051_ALU_XOR: begin
des_acc = src1 ^ src2;
des1 = src1 ^ src2;
des2 = 8'h00;
desCy = srcCy ^ bit_in;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation or
// bit operation or
`OC8051_ALU_OR: begin
des_acc = src1 | src2;
des1 = src1 | src2;
des2 = 8'h00;
desCy = srcCy | bit_in;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation rotate left
// bit operation cy= cy or (not ram)
`OC8051_ALU_RL: begin
des_acc = {src1[6:0], src1[7]};
des1 = src1 ;
des2 = 8'h00;
desCy = srcCy | !bit_in;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation rotate left with carry and swap nibbles
`OC8051_ALU_RLC: begin
des_acc = {src1[6:0], srcCy};
des1 = src1 ;
des2 = {src1[3:0], src1[7:4]};
desCy = src1[7];
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation rotate right
`OC8051_ALU_RR: begin
des_acc = {src1[0], src1[7:1]};
des1 = src1 ;
des2 = 8'h00;
desCy = srcCy & !bit_in;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation rotate right with carry
`OC8051_ALU_RRC: begin
des_acc = {srcCy, src1[7:1]};
des1 = src1 ;
des2 = 8'h00;
desCy = src1[0];
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation pcs Add
`OC8051_ALU_INC: begin
if (srcCy) begin
des_acc = dec[7:0];
des1 = dec[7:0];
des2 = dec[15:8];
end else begin
des_acc = inc[7:0];
des1 = inc[7:0];
des2 = inc[15:8];
end
desCy = 1'b0;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
//operation exchange
//if carry = 0 exchange low order digit
`OC8051_ALU_XCH: begin
if (srcCy)
begin
des_acc = src2;
des1 = src2;
des2 = src1;
end else begin
des_acc = {src1[7:4],src2[3:0]};
des1 = {src1[7:4],src2[3:0]};
des2 = {src2[7:4],src1[3:0]};
end
desCy = 1'b0;
desAc = 1'b0;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
`OC8051_ALU_NOP: begin
des_acc = src1;
des1 = src1;
des2 = src2;
desCy = srcCy;
desAc = srcAc;
desOv = 1'b0;
enable_mul = 1'b0;
enable_div = 1'b0;
end
endcase
end
 
endmodule
/turbo8051/trunk/rtl/8051/oc8051_multiply.v
110,3 → 110,4
end
 
endmodule
 
/turbo8051/trunk/rtl/8051/oc8051_rom.v
888,6 → 888,9
ea_int <= #1 1'b1;
else ea_int <= #1 !ea;
 
`elsif OC8051_ACTEL_ROM
 
 
`else
 
 
/turbo8051/trunk/rtl/8051/oc8051_top.v
1,854 → 1,854
//////////////////////////////////////////////////////////////////////
//// ////
//// 8051 cores top level module ////
//// ////
//// This file is part of the 8051 cores project ////
//// http://www.opencores.org/cores/8051/ ////
//// ////
//// Description ////
//// 8051 definitions. ////
//// ////
//// To Do: ////
//// nothing ////
//// ////
//// Author(s): ////
//// - Simon Teran, simont@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.32 2003/06/20 13:36:37 simont
// ram modules added.
//
// Revision 1.31 2003/06/17 14:17:22 simont
// BIST signals added.
//
// Revision 1.30 2003/06/03 16:51:24 simont
// include "8051_defines" added.
//
// Revision 1.29 2003/05/07 12:36:03 simont
// chsnge comp.des to des1
//
// Revision 1.28 2003/05/06 09:41:35 simont
// remove define OC8051_AS2_PCL, chane signal src_sel2 to 2 bit wide.
//
// Revision 1.27 2003/05/05 15:46:37 simont
// add aditional alu destination to solve critical path.
//
// Revision 1.26 2003/04/29 11:24:31 simont
// fix bug in case execution of two data dependent instructions.
//
// Revision 1.25 2003/04/25 17:15:51 simont
// change branch instruction execution (reduse needed clock periods).
//
// Revision 1.24 2003/04/11 10:05:59 simont
// deifne OC8051_ROM added
//
// Revision 1.23 2003/04/10 12:43:19 simont
// defines for pherypherals added
//
// Revision 1.22 2003/04/09 16:24:04 simont
// change wr_sft to 2 bit wire.
//
// Revision 1.21 2003/04/09 15:49:42 simont
// Register oc8051_sfr dato output, add signal wait_data.
//
// Revision 1.20 2003/04/03 19:13:28 simont
// Include instruction cache.
//
// Revision 1.19 2003/04/02 15:08:30 simont
// raname signals.
//
// Revision 1.18 2003/01/13 14:14:41 simont
// replace some modules
//
// Revision 1.17 2002/11/05 17:23:54 simont
// add module oc8051_sfr, 256 bytes internal ram
//
// Revision 1.16 2002/10/28 14:55:00 simont
// fix bug in interface to external data ram
//
// Revision 1.15 2002/10/23 16:53:39 simont
// fix bugs in instruction interface
//
// Revision 1.14 2002/10/17 18:50:00 simont
// cahnge interface to instruction rom
//
// Revision 1.13 2002/09/30 17:33:59 simont
// prepared header
//
//
 
// synopsys translate_off
`include "oc8051_timescale.v"
// synopsys translate_on
 
`include "oc8051_defines.v"
 
module oc8051_top (wb_rst_i, wb_clk_i,
//interface to instruction rom
wbi_adr_o,
wbi_dat_i,
wbi_stb_o,
wbi_ack_i,
wbi_cyc_o,
wbi_err_i,
 
//interface to data ram
wbd_dat_i,
wbd_dat_o,
wbd_adr_o,
wbd_we_o,
wbd_ack_i,
wbd_stb_o,
wbd_cyc_o,
wbd_err_i,
 
// interrupt interface
int0_i,
int1_i,
 
 
// port interface
`ifdef OC8051_PORTS
`ifdef OC8051_PORT0
p0_i,
p0_o,
`endif
 
`ifdef OC8051_PORT1
p1_i,
p1_o,
`endif
 
`ifdef OC8051_PORT2
p2_i,
p2_o,
`endif
 
`ifdef OC8051_PORT3
p3_i,
p3_o,
`endif
`endif
 
// serial interface
`ifdef OC8051_UART
rxd_i, txd_o,
`endif
 
// counter interface
`ifdef OC8051_TC01
t0_i, t1_i,
`endif
 
`ifdef OC8051_TC2
t2_i, t2ex_i,
`endif
 
// BIST
`ifdef OC8051_BIST
scanb_rst,
scanb_clk,
scanb_si,
scanb_so,
scanb_en,
`endif
// external access (active low)
ea_in
);
 
 
 
input wb_rst_i, // reset input
wb_clk_i, // clock input
int0_i, // interrupt 0
int1_i, // interrupt 1
ea_in, // external access
wbd_ack_i, // data acknowalge
wbi_ack_i, // instruction acknowlage
wbd_err_i, // data error
wbi_err_i; // instruction error
 
input [7:0] wbd_dat_i; // ram data input
input [31:0] wbi_dat_i; // rom data input
 
output wbd_we_o, // data write enable
wbd_stb_o, // data strobe
wbd_cyc_o, // data cycle
wbi_stb_o, // instruction strobe
wbi_cyc_o; // instruction cycle
 
output [7:0] wbd_dat_o; // data output
 
output [15:0] wbd_adr_o, // data address
wbi_adr_o; // instruction address
 
`ifdef OC8051_PORTS
 
`ifdef OC8051_PORT0
input [7:0] p0_i; // port 0 input
output [7:0] p0_o; // port 0 output
`endif
 
`ifdef OC8051_PORT1
input [7:0] p1_i; // port 1 input
output [7:0] p1_o; // port 1 output
`endif
 
`ifdef OC8051_PORT2
input [7:0] p2_i; // port 2 input
output [7:0] p2_o; // port 2 output
`endif
 
`ifdef OC8051_PORT3
input [7:0] p3_i; // port 3 input
output [7:0] p3_o; // port 3 output
`endif
 
`endif
 
 
 
 
 
 
`ifdef OC8051_UART
input rxd_i; // receive
output txd_o; // transnmit
`endif
 
`ifdef OC8051_TC01
input t0_i, // counter 0 input
t1_i; // counter 1 input
`endif
 
`ifdef OC8051_TC2
input t2_i, // counter 2 input
t2ex_i; //
`endif
 
`ifdef OC8051_BIST
input scanb_rst;
input scanb_clk;
input scanb_si;
output scanb_so;
input scanb_en;
wire scanb_soi;
`endif
 
wire [7:0] dptr_hi,
dptr_lo,
ri,
data_out,
op1,
op2,
op3,
acc,
p0_out,
p1_out,
p2_out,
p3_out,
sp,
sp_w;
 
wire [31:0] idat_onchip;
 
wire [15:0] pc;
 
assign wbd_cyc_o = wbd_stb_o;
 
wire src_sel3;
wire [1:0] wr_sfr,
src_sel2;
wire [2:0] ram_rd_sel, // ram read
ram_wr_sel, // ram write
src_sel1;
 
wire [7:0] ram_data,
ram_out, //data from ram
sfr_out,
wr_dat,
wr_addr, //ram write addres
rd_addr; //data ram read addres
wire sfr_bit;
 
wire [1:0] cy_sel, //carry select; from decoder to cy_selct1
bank_sel;
wire rom_addr_sel, //rom addres select; alu or pc
rmw,
ea_int;
 
wire reti,
intr,
int_ack,
istb;
wire [7:0] int_src;
 
wire mem_wait;
wire [2:0] mem_act;
wire [3:0] alu_op; //alu operation (from decoder)
wire [1:0] psw_set; //write to psw or not; from decoder to psw (through register)
 
wire [7:0] src1, //alu sources 1
src2, //alu sources 2
src3, //alu sources 3
des_acc,
des1, //alu destination 1
des2; //alu destinations 2
wire desCy, //carry out
desAc,
desOv, //overflow
alu_cy,
wr, //write to data ram
wr_o;
 
wire rd, //read program rom
pc_wr;
wire [2:0] pc_wr_sel; //program counter write select (from decoder to pc)
 
wire [7:0] op1_n, //from memory_interface to decoder
op2_n,
op3_n;
 
wire [1:0] comp_sel; //select source1 and source2 to compare
wire eq, //result (from comp1 to decoder)
srcAc,
cy,
rd_ind,
wr_ind,
comp_wait;
wire [2:0] op1_cur;
 
wire bit_addr, //bit addresable instruction
bit_data, //bit data from ram to ram_select
bit_out, //bit data from ram_select to alu and cy_select
bit_addr_o,
wait_data;
 
//
// cpu to cache/wb_interface
wire iack_i,
istb_o,
icyc_o;
wire [31:0] idat_i;
wire [15:0] iadr_o;
 
 
//
// decoder
oc8051_decoder oc8051_decoder1(
.clk (wb_clk_i ),
.rst (wb_rst_i ),
.op_in (op1_n ),
.op1_c (op1_cur ),
.ram_rd_sel_o (ram_rd_sel ),
.ram_wr_sel_o (ram_wr_sel ),
.bit_addr (bit_addr ),
 
.src_sel1 (src_sel1 ),
.src_sel2 (src_sel2 ),
.src_sel3 (src_sel3 ),
 
.alu_op_o (alu_op ),
.psw_set (psw_set ),
.cy_sel (cy_sel ),
.wr_o (wr ),
.pc_wr (pc_wr ),
.pc_sel (pc_wr_sel ),
.comp_sel (comp_sel ),
.eq (eq ),
.wr_sfr_o (wr_sfr ),
.rd (rd ),
.rmw (rmw ),
.istb (istb ),
.mem_act (mem_act ),
.mem_wait (mem_wait ),
.wait_data (wait_data )
);
 
 
wire [7:0] sub_result;
//
//alu
oc8051_alu oc8051_alu1(
.rst (wb_rst_i ),
.clk (wb_clk_i ),
.op_code (alu_op ),
.src1 (src1 ),
.src2 (src2 ),
.src3 (src3 ),
.srcCy (alu_cy ),
.srcAc (srcAc ),
.des_acc (des_acc ),
.sub_result (sub_result ),
.des1 (des1 ),
.des2 (des2 ),
.desCy (desCy ),
.desAc (desAc ),
.desOv (desOv ),
.bit_in(bit_out)
);
 
//
//data ram
oc8051_ram_top oc8051_ram_top1(
.clk (wb_clk_i ),
.rst (wb_rst_i ),
.rd_addr (rd_addr ),
.rd_data (ram_data ),
.wr_addr (wr_addr ),
.bit_addr (bit_addr_o ),
.wr_data (wr_dat ),
.wr (wr_o &&
(!wr_addr[7] || wr_ind)),
.bit_data_in (desCy ),
.bit_data_out (bit_data )
`ifdef OC8051_BIST
,
.scanb_rst (scanb_rst ),
.scanb_clk (scanb_clk ),
.scanb_si (scanb_soi ),
.scanb_so (scanb_so ),
.scanb_en (scanb_en )
`endif
);
 
//
 
oc8051_alu_src_sel oc8051_alu_src_sel1(
.clk (wb_clk_i ),
.rst (wb_rst_i ),
.rd (rd ),
 
.sel1 (src_sel1 ),
.sel2 (src_sel2 ),
.sel3 (src_sel3 ),
 
.acc (acc ),
.ram (ram_out ),
.pc (pc ),
.dptr ({dptr_hi, dptr_lo} ),
.op1 (op1_n ),
.op2 (op2_n ),
.op3 (op3_n ),
 
.src1 (src1 ),
.src2 (src2 ),
.src3 (src3 )
);
 
 
//
//
oc8051_comp oc8051_comp1(
.sel (comp_sel ),
.eq (eq ),
.b_in (bit_out ),
.cy (cy ),
.acc (acc ),
.des (sub_result )
);
 
 
//
//program rom
`ifdef OC8051_ROM
oc8051_rom oc8051_rom1(
.rst (wb_rst_i ),
.clk (wb_clk_i ),
.ea_int (ea_int ),
.addr (iadr_o ),
.data_o (idat_onchip )
);
`else
assign ea_int = 1'b0;
assign idat_onchip = 32'h0;
`ifdef OC8051_SIMULATION
 
initial
begin
$display("\t * ");
$display("\t * Internal rom disabled!!!");
$display("\t * ");
end
 
`endif
 
`endif
 
//
//
oc8051_cy_select oc8051_cy_select1(
.cy_sel (cy_sel ),
.cy_in (cy ),
.data_in (bit_out ),
.data_out (alu_cy )
);
//
//
oc8051_indi_addr oc8051_indi_addr1 (
.clk (wb_clk_i ),
.rst (wb_rst_i ),
.wr_addr (wr_addr ),
.data_in (wr_dat ),
.wr (wr_o ),
.wr_bit (bit_addr_o ),
.ri_out (ri ),
.sel (op1_cur[0] ),
.bank (bank_sel )
);
 
 
 
assign icyc_o = istb_o;
//
//
oc8051_memory_interface oc8051_memory_interface1(
.clk (wb_clk_i ),
.rst (wb_rst_i ),
// internal ram
.wr_i (wr ),
.wr_o (wr_o ),
.wr_bit_i (bit_addr ),
.wr_bit_o (bit_addr_o ),
.wr_dat (wr_dat ),
.des_acc (des_acc ),
.des1 (des1 ),
.des2 (des2 ),
.rd_addr (rd_addr ),
.wr_addr (wr_addr ),
.wr_ind (wr_ind ),
.bit_in (bit_data ),
.in_ram (ram_data ),
.sfr (sfr_out ),
.sfr_bit (sfr_bit ),
.bit_out (bit_out ),
.iram_out (ram_out ),
 
// external instrauction rom
.iack_i (iack_i ),
.iadr_o (iadr_o ),
.idat_i (idat_i ),
.istb_o (istb_o ),
 
// internal instruction rom
.idat_onchip (idat_onchip ),
 
// data memory
.dadr_o (wbd_adr_o ),
.ddat_o (wbd_dat_o ),
.dwe_o (wbd_we_o ),
.dstb_o (wbd_stb_o ),
.ddat_i (wbd_dat_i ),
.dack_i (wbd_ack_i ),
 
// from decoder
.rd_sel (ram_rd_sel ),
.wr_sel (ram_wr_sel ),
.rn ({bank_sel, op1_cur}),
.rd_ind (rd_ind ),
.rd (rd ),
.mem_act (mem_act ),
.mem_wait (mem_wait ),
 
// external access
.ea (ea_in ),
.ea_int (ea_int ),
 
// instructions outputs to cpu
.op1_out (op1_n ),
.op2_out (op2_n ),
.op3_out (op3_n ),
 
// interrupt interface
.intr (intr ),
.int_v(int_src),
.int_ack (int_ack ),
.istb (istb ),
.reti (reti ),
 
//pc
.pc_wr_sel (pc_wr_sel ),
.pc_wr (pc_wr & comp_wait ),
.pc (pc ),
 
// sfr's
.sp_w (sp_w ),
.dptr ({dptr_hi, dptr_lo} ),
.ri (ri ),
.acc (acc ),
.sp (sp )
);
 
 
//
//
 
oc8051_sfr oc8051_sfr1(
.rst (wb_rst_i ),
.clk (wb_clk_i ),
.adr0 (rd_addr[7:0] ),
.adr1 (wr_addr[7:0] ),
.dat0 (sfr_out ),
.dat1 (wr_dat ),
.dat2 (des2 ),
.des_acc (des_acc ),
.we (wr_o && !wr_ind ),
.bit_in (desCy ),
.bit_out (sfr_bit ),
.wr_bit (bit_addr_o ),
.ram_rd_sel (ram_rd_sel ),
.ram_wr_sel (ram_wr_sel ),
.wr_sfr (wr_sfr ),
.comp_sel (comp_sel ),
.comp_wait (comp_wait ),
// acc
.acc (acc ),
// sp
.sp (sp ),
.sp_w (sp_w ),
// psw
.bank_sel (bank_sel ),
.desAc (desAc ),
.desOv (desOv ),
.psw_set (psw_set ),
.srcAc (srcAc ),
.cy (cy ),
// ports
.rmw (rmw ),
 
`ifdef OC8051_PORTS
`ifdef OC8051_PORT0
.p0_out (p0_o ),
.p0_in (p0_i ),
`endif
 
`ifdef OC8051_PORT1
.p1_out (p1_o ),
.p1_in (p1_i ),
`endif
 
`ifdef OC8051_PORT2
.p2_out (p2_o ),
.p2_in (p2_i ),
`endif
 
`ifdef OC8051_PORT3
.p3_out (p3_o ),
.p3_in (p3_i ),
`endif
`endif
 
// uart
`ifdef OC8051_UART
.rxd (rxd_i ),
.txd (txd_o ),
`endif
 
// int
.int_ack (int_ack ),
.intr (intr ),
.int0 (int0_i ),
.int1 (int1_i ),
.reti (reti ),
.int_src (int_src ),
 
// t/c 0,1
`ifdef OC8051_TC01
.t0 (t0_i ),
.t1 (t1_i ),
`endif
 
// t/c 2
`ifdef OC8051_TC2
.t2 (t2_i ),
.t2ex (t2ex_i ),
`endif
 
// dptr
.dptr_hi (dptr_hi ),
.dptr_lo (dptr_lo ),
.wait_data (wait_data )
);
 
 
 
 
`ifdef OC8051_CACHE
 
 
oc8051_icache oc8051_icache1(
.rst (wb_rst_i ),
.clk (wb_clk_i ),
// cpu
.adr_i (iadr_o ),
.dat_o (idat_i ),
.stb_i (istb_o ),
.ack_o (iack_i ),
.cyc_i (icyc_o ),
// pins
.dat_i (wbi_dat_i ),
.stb_o (wbi_stb_o ),
.adr_o (wbi_adr_o ),
.ack_i (wbi_ack_i ),
.cyc_o (wbi_cyc_o )
`ifdef OC8051_BIST
,
.scanb_rst (scanb_rst ),
.scanb_clk (scanb_clk ),
.scanb_si (scanb_si ),
.scanb_so (scanb_soi ),
.scanb_en (scanb_en )
`endif
);
 
defparam oc8051_icache1.ADR_WIDTH = 6; // cache address wihth
defparam oc8051_icache1.LINE_WIDTH = 2; // line address width (2 => 4x32)
defparam oc8051_icache1.BL_NUM = 15; // number of blocks (2^BL_WIDTH-1); BL_WIDTH = ADR_WIDTH - LINE_WIDTH
defparam oc8051_icache1.CACHE_RAM = 64; // cache ram x 32 (2^ADR_WIDTH)
 
 
`ifdef OC8051_SIMULATION
 
initial
begin
#1
$display("\t * ");
$display("\t * External rom interface: cache");
$display("\t * ");
end
 
`endif
 
 
 
//
// no cache
//
`else
 
`ifdef OC8051_BIST
assign scanb_soi=scanb_si;
`endif
 
`ifdef OC8051_WB
 
oc8051_wb_iinterface oc8051_wb_iinterface(
.rst (wb_rst_i ),
.clk (wb_clk_i ),
// cpu
.adr_i (iadr_o ),
.dat_o (idat_i ),
.stb_i (istb_o ),
.ack_o (iack_i ),
.cyc_i (icyc_o ),
// external rom
.dat_i (wbi_dat_i ),
.stb_o (wbi_stb_o ),
.adr_o (wbi_adr_o ),
.ack_i (wbi_ack_i ),
.cyc_o (wbi_cyc_o )
);
 
`ifdef OC8051_SIMULATION
 
initial
begin
#1
$display("\t * ");
$display("\t * External rom interface: WB interface");
$display("\t * ");
end
 
`endif
 
`else
 
assign wbi_adr_o = iadr_o ;
assign idat_i = wbi_dat_i ;
assign wbi_stb_o = 1'b1 ;
assign iack_i = wbi_ack_i ;
assign wbi_cyc_o = 1'b1 ;
 
`ifdef OC8051_SIMULATION
 
initial
begin
#1
$display("\t * ");
$display("\t * External rom interface: Pipelined interface");
$display("\t * ");
end
 
`endif
 
 
`endif
 
`endif
 
 
// synopsys translate_on
// Debug Purpose only
// Stack Pointer Push & Pop analysis
reg [7:0] StackMem[$];
reg [7:0] stack_pop;
reg [7:0] pushpop_cnt;
 
// Assumption, Both Write and Read access will not be
// possbile in single clock cycle
always @(posedge wb_clk_i or posedge wb_rst_i)
begin
if(wb_rst_i) begin
pushpop_cnt = 0;
end
else begin
if(ram_wr_sel==`OC8051_RWS_SP) begin
StackMem.push_back(wr_dat);
pushpop_cnt = pushpop_cnt + 1;
end
if(ram_rd_sel==`OC8051_RRS_SP) begin
stack_pop = StackMem.pop_back();
pushpop_cnt = pushpop_cnt - 1;
#2 // Add 1ns Delay to take care of Ram Dealy
if(stack_pop != ram_data) begin
$display("ERROR: Invalid Stack Pointer Pop Detected, Exp: %x,Rxd:%x",stack_pop,ram_data);
$stop;
end
end
end
end
 
// synopsys translate_off
 
endmodule
//////////////////////////////////////////////////////////////////////
//// ////
//// 8051 cores top level module ////
//// ////
//// This file is part of the 8051 cores project ////
//// http://www.opencores.org/cores/8051/ ////
//// ////
//// Description ////
//// 8051 definitions. ////
//// ////
//// To Do: ////
//// nothing ////
//// ////
//// Author(s): ////
//// - Simon Teran, simont@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.32 2003/06/20 13:36:37 simont
// ram modules added.
//
// Revision 1.31 2003/06/17 14:17:22 simont
// BIST signals added.
//
// Revision 1.30 2003/06/03 16:51:24 simont
// include "8051_defines" added.
//
// Revision 1.29 2003/05/07 12:36:03 simont
// chsnge comp.des to des1
//
// Revision 1.28 2003/05/06 09:41:35 simont
// remove define OC8051_AS2_PCL, chane signal src_sel2 to 2 bit wide.
//
// Revision 1.27 2003/05/05 15:46:37 simont
// add aditional alu destination to solve critical path.
//
// Revision 1.26 2003/04/29 11:24:31 simont
// fix bug in case execution of two data dependent instructions.
//
// Revision 1.25 2003/04/25 17:15:51 simont
// change branch instruction execution (reduse needed clock periods).
//
// Revision 1.24 2003/04/11 10:05:59 simont
// deifne OC8051_ROM added
//
// Revision 1.23 2003/04/10 12:43:19 simont
// defines for pherypherals added
//
// Revision 1.22 2003/04/09 16:24:04 simont
// change wr_sft to 2 bit wire.
//
// Revision 1.21 2003/04/09 15:49:42 simont
// Register oc8051_sfr dato output, add signal wait_data.
//
// Revision 1.20 2003/04/03 19:13:28 simont
// Include instruction cache.
//
// Revision 1.19 2003/04/02 15:08:30 simont
// raname signals.
//
// Revision 1.18 2003/01/13 14:14:41 simont
// replace some modules
//
// Revision 1.17 2002/11/05 17:23:54 simont
// add module oc8051_sfr, 256 bytes internal ram
//
// Revision 1.16 2002/10/28 14:55:00 simont
// fix bug in interface to external data ram
//
// Revision 1.15 2002/10/23 16:53:39 simont
// fix bugs in instruction interface
//
// Revision 1.14 2002/10/17 18:50:00 simont
// cahnge interface to instruction rom
//
// Revision 1.13 2002/09/30 17:33:59 simont
// prepared header
//
//
 
// synopsys translate_off
`include "oc8051_timescale.v"
// synopsys translate_on
 
`include "oc8051_defines.v"
 
module oc8051_top (wb_rst_i, wb_clk_i,
//interface to instruction rom
wbi_adr_o,
wbi_dat_i,
wbi_stb_o,
wbi_ack_i,
wbi_cyc_o,
wbi_err_i,
 
//interface to data ram
wbd_dat_i,
wbd_dat_o,
wbd_adr_o,
wbd_we_o,
wbd_ack_i,
wbd_stb_o,
wbd_cyc_o,
wbd_err_i,
 
// interrupt interface
int0_i,
int1_i,
 
 
// port interface
`ifdef OC8051_PORTS
`ifdef OC8051_PORT0
p0_i,
p0_o,
`endif
 
`ifdef OC8051_PORT1
p1_i,
p1_o,
`endif
 
`ifdef OC8051_PORT2
p2_i,
p2_o,
`endif
 
`ifdef OC8051_PORT3
p3_i,
p3_o,
`endif
`endif
 
// serial interface
`ifdef OC8051_UART
rxd_i, txd_o,
`endif
 
// counter interface
`ifdef OC8051_TC01
t0_i, t1_i,
`endif
 
`ifdef OC8051_TC2
t2_i, t2ex_i,
`endif
 
// BIST
`ifdef OC8051_BIST
scanb_rst,
scanb_clk,
scanb_si,
scanb_so,
scanb_en,
`endif
// external access (active low)
ea_in
);
 
 
 
input wb_rst_i, // reset input
wb_clk_i, // clock input
int0_i, // interrupt 0
int1_i, // interrupt 1
ea_in, // external access
wbd_ack_i, // data acknowalge
wbi_ack_i, // instruction acknowlage
wbd_err_i, // data error
wbi_err_i; // instruction error
 
input [7:0] wbd_dat_i; // ram data input
input [31:0] wbi_dat_i; // rom data input
 
output wbd_we_o, // data write enable
wbd_stb_o, // data strobe
wbd_cyc_o, // data cycle
wbi_stb_o, // instruction strobe
wbi_cyc_o; // instruction cycle
 
output [7:0] wbd_dat_o; // data output
 
output [15:0] wbd_adr_o, // data address
wbi_adr_o; // instruction address
 
`ifdef OC8051_PORTS
 
`ifdef OC8051_PORT0
input [7:0] p0_i; // port 0 input
output [7:0] p0_o; // port 0 output
`endif
 
`ifdef OC8051_PORT1
input [7:0] p1_i; // port 1 input
output [7:0] p1_o; // port 1 output
`endif
 
`ifdef OC8051_PORT2
input [7:0] p2_i; // port 2 input
output [7:0] p2_o; // port 2 output
`endif
 
`ifdef OC8051_PORT3
input [7:0] p3_i; // port 3 input
output [7:0] p3_o; // port 3 output
`endif
 
`endif
 
 
 
 
 
 
`ifdef OC8051_UART
input rxd_i; // receive
output txd_o; // transnmit
`endif
 
`ifdef OC8051_TC01
input t0_i, // counter 0 input
t1_i; // counter 1 input
`endif
 
`ifdef OC8051_TC2
input t2_i, // counter 2 input
t2ex_i; //
`endif
 
`ifdef OC8051_BIST
input scanb_rst;
input scanb_clk;
input scanb_si;
output scanb_so;
input scanb_en;
wire scanb_soi;
`endif
 
wire [7:0] dptr_hi,
dptr_lo,
ri,
data_out,
op1,
op2,
op3,
acc,
p0_out,
p1_out,
p2_out,
p3_out,
sp,
sp_w;
 
wire [31:0] idat_onchip;
 
wire [15:0] pc;
 
assign wbd_cyc_o = wbd_stb_o;
 
wire src_sel3;
wire [1:0] wr_sfr,
src_sel2;
wire [2:0] ram_rd_sel, // ram read
ram_wr_sel, // ram write
src_sel1;
 
wire [7:0] ram_data,
ram_out, //data from ram
sfr_out,
wr_dat,
wr_addr, //ram write addres
rd_addr; //data ram read addres
wire sfr_bit;
 
wire [1:0] cy_sel, //carry select; from decoder to cy_selct1
bank_sel;
wire rom_addr_sel, //rom addres select; alu or pc
rmw,
ea_int;
 
wire reti,
intr,
int_ack,
istb;
wire [7:0] int_src;
 
wire mem_wait;
wire [2:0] mem_act;
wire [3:0] alu_op; //alu operation (from decoder)
wire [1:0] psw_set; //write to psw or not; from decoder to psw (through register)
 
wire [7:0] src1, //alu sources 1
src2, //alu sources 2
src3, //alu sources 3
des_acc,
des1, //alu destination 1
des2; //alu destinations 2
wire desCy, //carry out
desAc,
desOv, //overflow
alu_cy,
wr, //write to data ram
wr_o;
 
wire rd, //read program rom
pc_wr;
wire [2:0] pc_wr_sel; //program counter write select (from decoder to pc)
 
wire [7:0] op1_n, //from memory_interface to decoder
op2_n,
op3_n;
 
wire [1:0] comp_sel; //select source1 and source2 to compare
wire eq, //result (from comp1 to decoder)
srcAc,
cy,
rd_ind,
wr_ind,
comp_wait;
wire [2:0] op1_cur;
 
wire bit_addr, //bit addresable instruction
bit_data, //bit data from ram to ram_select
bit_out, //bit data from ram_select to alu and cy_select
bit_addr_o,
wait_data;
 
//
// cpu to cache/wb_interface
wire iack_i,
istb_o,
icyc_o;
wire [31:0] idat_i;
wire [15:0] iadr_o;
 
 
//
// decoder
oc8051_decoder oc8051_decoder1(
.clk (wb_clk_i ),
.rst (wb_rst_i ),
.op_in (op1_n ),
.op1_c (op1_cur ),
.ram_rd_sel_o (ram_rd_sel ),
.ram_wr_sel_o (ram_wr_sel ),
.bit_addr (bit_addr ),
 
.src_sel1 (src_sel1 ),
.src_sel2 (src_sel2 ),
.src_sel3 (src_sel3 ),
 
.alu_op_o (alu_op ),
.psw_set (psw_set ),
.cy_sel (cy_sel ),
.wr_o (wr ),
.pc_wr (pc_wr ),
.pc_sel (pc_wr_sel ),
.comp_sel (comp_sel ),
.eq (eq ),
.wr_sfr_o (wr_sfr ),
.rd (rd ),
.rmw (rmw ),
.istb (istb ),
.mem_act (mem_act ),
.mem_wait (mem_wait ),
.wait_data (wait_data )
);
 
 
wire [7:0] sub_result;
//
//alu
oc8051_alu oc8051_alu1(
.rst (wb_rst_i ),
.clk (wb_clk_i ),
.op_code (alu_op ),
.src1 (src1 ),
.src2 (src2 ),
.src3 (src3 ),
.srcCy (alu_cy ),
.srcAc (srcAc ),
.des_acc (des_acc ),
.sub_result (sub_result ),
.des1 (des1 ),
.des2 (des2 ),
.desCy (desCy ),
.desAc (desAc ),
.desOv (desOv ),
.bit_in(bit_out)
);
 
//
//data ram
oc8051_ram_top oc8051_ram_top1(
.clk (wb_clk_i ),
.rst (wb_rst_i ),
.rd_addr (rd_addr ),
.rd_data (ram_data ),
.wr_addr (wr_addr ),
.bit_addr (bit_addr_o ),
.wr_data (wr_dat ),
.wr (wr_o &&
(!wr_addr[7] || wr_ind)),
.bit_data_in (desCy ),
.bit_data_out (bit_data )
`ifdef OC8051_BIST
,
.scanb_rst (scanb_rst ),
.scanb_clk (scanb_clk ),
.scanb_si (scanb_soi ),
.scanb_so (scanb_so ),
.scanb_en (scanb_en )
`endif
);
 
//
 
oc8051_alu_src_sel oc8051_alu_src_sel1(
.clk (wb_clk_i ),
.rst (wb_rst_i ),
.rd (rd ),
 
.sel1 (src_sel1 ),
.sel2 (src_sel2 ),
.sel3 (src_sel3 ),
 
.acc (acc ),
.ram (ram_out ),
.pc (pc ),
.dptr ({dptr_hi, dptr_lo} ),
.op1 (op1_n ),
.op2 (op2_n ),
.op3 (op3_n ),
 
.src1 (src1 ),
.src2 (src2 ),
.src3 (src3 )
);
 
 
//
//
oc8051_comp oc8051_comp1(
.sel (comp_sel ),
.eq (eq ),
.b_in (bit_out ),
.cy (cy ),
.acc (acc ),
.des (sub_result )
);
 
 
//
//program rom
`ifdef OC8051_ROM
oc8051_rom oc8051_rom1(
.rst (wb_rst_i ),
.clk (wb_clk_i ),
.ea_int (ea_int ),
.addr (iadr_o ),
.data_o (idat_onchip )
);
`else
assign ea_int = 1'b0;
assign idat_onchip = 32'h0;
`ifdef OC8051_SIMULATION
 
initial
begin
$display("\t * ");
$display("\t * Internal rom disabled!!!");
$display("\t * ");
end
 
`endif
 
`endif
 
//
//
oc8051_cy_select oc8051_cy_select1(
.cy_sel (cy_sel ),
.cy_in (cy ),
.data_in (bit_out ),
.data_out (alu_cy )
);
//
//
oc8051_indi_addr oc8051_indi_addr1 (
.clk (wb_clk_i ),
.rst (wb_rst_i ),
.wr_addr (wr_addr ),
.data_in (wr_dat ),
.wr (wr_o ),
.wr_bit (bit_addr_o ),
.ri_out (ri ),
.sel (op1_cur[0] ),
.bank (bank_sel )
);
 
 
 
assign icyc_o = istb_o;
//
//
oc8051_memory_interface oc8051_memory_interface1(
.clk (wb_clk_i ),
.rst (wb_rst_i ),
// internal ram
.wr_i (wr ),
.wr_o (wr_o ),
.wr_bit_i (bit_addr ),
.wr_bit_o (bit_addr_o ),
.wr_dat (wr_dat ),
.des_acc (des_acc ),
.des1 (des1 ),
.des2 (des2 ),
.rd_addr (rd_addr ),
.wr_addr (wr_addr ),
.wr_ind (wr_ind ),
.bit_in (bit_data ),
.in_ram (ram_data ),
.sfr (sfr_out ),
.sfr_bit (sfr_bit ),
.bit_out (bit_out ),
.iram_out (ram_out ),
 
// external instrauction rom
.iack_i (iack_i ),
.iadr_o (iadr_o ),
.idat_i (idat_i ),
.istb_o (istb_o ),
 
// internal instruction rom
.idat_onchip (idat_onchip ),
 
// data memory
.dadr_o (wbd_adr_o ),
.ddat_o (wbd_dat_o ),
.dwe_o (wbd_we_o ),
.dstb_o (wbd_stb_o ),
.ddat_i (wbd_dat_i ),
.dack_i (wbd_ack_i ),
 
// from decoder
.rd_sel (ram_rd_sel ),
.wr_sel (ram_wr_sel ),
.rn ({bank_sel, op1_cur}),
.rd_ind (rd_ind ),
.rd (rd ),
.mem_act (mem_act ),
.mem_wait (mem_wait ),
 
// external access
.ea (ea_in ),
.ea_int (ea_int ),
 
// instructions outputs to cpu
.op1_out (op1_n ),
.op2_out (op2_n ),
.op3_out (op3_n ),
 
// interrupt interface
.intr (intr ),
.int_v(int_src),
.int_ack (int_ack ),
.istb (istb ),
.reti (reti ),
 
//pc
.pc_wr_sel (pc_wr_sel ),
.pc_wr (pc_wr & comp_wait ),
.pc (pc ),
 
// sfr's
.sp_w (sp_w ),
.dptr ({dptr_hi, dptr_lo} ),
.ri (ri ),
.acc (acc ),
.sp (sp )
);
 
 
//
//
 
oc8051_sfr oc8051_sfr1(
.rst (wb_rst_i ),
.clk (wb_clk_i ),
.adr0 (rd_addr[7:0] ),
.adr1 (wr_addr[7:0] ),
.dat0 (sfr_out ),
.dat1 (wr_dat ),
.dat2 (des2 ),
.des_acc (des_acc ),
.we (wr_o && !wr_ind ),
.bit_in (desCy ),
.bit_out (sfr_bit ),
.wr_bit (bit_addr_o ),
.ram_rd_sel (ram_rd_sel ),
.ram_wr_sel (ram_wr_sel ),
.wr_sfr (wr_sfr ),
.comp_sel (comp_sel ),
.comp_wait (comp_wait ),
// acc
.acc (acc ),
// sp
.sp (sp ),
.sp_w (sp_w ),
// psw
.bank_sel (bank_sel ),
.desAc (desAc ),
.desOv (desOv ),
.psw_set (psw_set ),
.srcAc (srcAc ),
.cy (cy ),
// ports
.rmw (rmw ),
 
`ifdef OC8051_PORTS
`ifdef OC8051_PORT0
.p0_out (p0_o ),
.p0_in (p0_i ),
`endif
 
`ifdef OC8051_PORT1
.p1_out (p1_o ),
.p1_in (p1_i ),
`endif
 
`ifdef OC8051_PORT2
.p2_out (p2_o ),
.p2_in (p2_i ),
`endif
 
`ifdef OC8051_PORT3
.p3_out (p3_o ),
.p3_in (p3_i ),
`endif
`endif
 
// uart
`ifdef OC8051_UART
.rxd (rxd_i ),
.txd (txd_o ),
`endif
 
// int
.int_ack (int_ack ),
.intr (intr ),
.int0 (int0_i ),
.int1 (int1_i ),
.reti (reti ),
.int_src (int_src ),
 
// t/c 0,1
`ifdef OC8051_TC01
.t0 (t0_i ),
.t1 (t1_i ),
`endif
 
// t/c 2
`ifdef OC8051_TC2
.t2 (t2_i ),
.t2ex (t2ex_i ),
`endif
 
// dptr
.dptr_hi (dptr_hi ),
.dptr_lo (dptr_lo ),
.wait_data (wait_data )
);
 
 
 
 
`ifdef OC8051_CACHE
 
 
oc8051_icache oc8051_icache1(
.rst (wb_rst_i ),
.clk (wb_clk_i ),
// cpu
.adr_i (iadr_o ),
.dat_o (idat_i ),
.stb_i (istb_o ),
.ack_o (iack_i ),
.cyc_i (icyc_o ),
// pins
.dat_i (wbi_dat_i ),
.stb_o (wbi_stb_o ),
.adr_o (wbi_adr_o ),
.ack_i (wbi_ack_i ),
.cyc_o (wbi_cyc_o )
`ifdef OC8051_BIST
,
.scanb_rst (scanb_rst ),
.scanb_clk (scanb_clk ),
.scanb_si (scanb_si ),
.scanb_so (scanb_soi ),
.scanb_en (scanb_en )
`endif
);
 
defparam oc8051_icache1.ADR_WIDTH = 6; // cache address wihth
defparam oc8051_icache1.LINE_WIDTH = 2; // line address width (2 => 4x32)
defparam oc8051_icache1.BL_NUM = 15; // number of blocks (2^BL_WIDTH-1); BL_WIDTH = ADR_WIDTH - LINE_WIDTH
defparam oc8051_icache1.CACHE_RAM = 64; // cache ram x 32 (2^ADR_WIDTH)
 
 
`ifdef OC8051_SIMULATION
 
initial
begin
#1
$display("\t * ");
$display("\t * External rom interface: cache");
$display("\t * ");
end
 
`endif
 
 
 
//
// no cache
//
`else
 
`ifdef OC8051_BIST
assign scanb_soi=scanb_si;
`endif
 
`ifdef OC8051_WB
 
oc8051_wb_iinterface oc8051_wb_iinterface(
.rst (wb_rst_i ),
.clk (wb_clk_i ),
// cpu
.adr_i (iadr_o ),
.dat_o (idat_i ),
.stb_i (istb_o ),
.ack_o (iack_i ),
.cyc_i (icyc_o ),
// external rom
.dat_i (wbi_dat_i ),
.stb_o (wbi_stb_o ),
.adr_o (wbi_adr_o ),
.ack_i (wbi_ack_i ),
.cyc_o (wbi_cyc_o )
);
 
`ifdef OC8051_SIMULATION
 
initial
begin
#1
$display("\t * ");
$display("\t * External rom interface: WB interface");
$display("\t * ");
end
 
`endif
 
`else
 
assign wbi_adr_o = iadr_o ;
assign idat_i = wbi_dat_i ;
assign wbi_stb_o = 1'b1 ;
assign iack_i = wbi_ack_i ;
assign wbi_cyc_o = 1'b1 ;
 
`ifdef OC8051_SIMULATION
 
initial
begin
#1
$display("\t * ");
$display("\t * External rom interface: Pipelined interface");
$display("\t * ");
end
 
`endif
 
 
`endif
 
`endif
 
 
// synopsys translate_off
// Debug Purpose only
// Stack Pointer Push & Pop analysis
reg [7:0] StackMem[$];
reg [7:0] stack_pop;
reg [7:0] pushpop_cnt;
 
// Assumption, Both Write and Read access will not be
// possbile in single clock cycle
always @(posedge wb_clk_i or posedge wb_rst_i)
begin
if(wb_rst_i) begin
pushpop_cnt = 0;
end
else begin
if(ram_wr_sel==`OC8051_RWS_SP) begin
StackMem.push_back(wr_dat);
pushpop_cnt = pushpop_cnt + 1;
end
if(ram_rd_sel==`OC8051_RRS_SP) begin
stack_pop = StackMem.pop_back();
pushpop_cnt = pushpop_cnt - 1;
#2 // Add 1ns Delay to take care of Ram Dealy
if(stack_pop != ram_data) begin
$display("ERROR: Invalid Stack Pointer Pop Detected, Exp: %x,Rxd:%x",stack_pop,ram_data);
$stop;
end
end
end
end
 
// synopsys translate_on
 
endmodule
/turbo8051/trunk/rtl/8051/oc8051_ram_256x8_two_bist.v
1,179 → 1,188
//////////////////////////////////////////////////////////////////////
//// ////
//// 8051 internal ram ////
//// ////
//// This file is part of the 8051 cores project ////
//// http://www.opencores.org/cores/8051/ ////
//// ////
//// Description ////
//// 256 bytes two port ram ////
//// ////
//// To Do: ////
//// nothing ////
//// ////
//// Author(s): ////
//// - Simon Teran, simont@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
//
 
// synopsys translate_off
`include "oc8051_timescale.v"
// synopsys translate_on
 
`include "oc8051_defines.v"
 
//
// two port ram
//
module oc8051_ram_256x8_two_bist (
clk,
rst,
rd_addr,
rd_data,
rd_en,
wr_addr,
wr_data,
wr_en,
wr
`ifdef OC8051_BIST
,
scanb_rst,
scanb_clk,
scanb_si,
scanb_so,
scanb_en
`endif
);
 
 
input clk,
wr,
rst,
rd_en,
wr_en;
input [7:0] wr_data;
input [7:0] rd_addr,
wr_addr;
output [7:0] rd_data;
 
`ifdef OC8051_BIST
input scanb_rst;
input scanb_clk;
input scanb_si;
output scanb_so;
input scanb_en;
`endif
 
 
`ifdef OC8051_RAM_XILINX
xilinx_ram_dp xilinx_ram(
// read port
.CLKA(clk),
.RSTA(rst),
.ENA(rd_en),
.ADDRA(rd_addr),
.DIA(8'h00),
.WEA(1'b0),
.DOA(rd_data),
// write port
.CLKB(clk),
.RSTB(rst),
.ENB(wr_en),
.ADDRB(wr_addr),
.DIB(wr_data),
.WEB(wr),
.DOB()
);
defparam
xilinx_ram.dwidth = 8,
xilinx_ram.awidth = 8;
 
`else
 
`ifdef OC8051_RAM_VIRTUALSILICON
 
`else
 
`ifdef OC8051_RAM_GENERIC
generic_dpram #(8, 8) oc8051_ram1(
.rclk ( clk ),
.rrst ( rst ),
.rce ( rd_en ),
.oe ( 1'b1 ),
.raddr ( rd_addr ),
.do ( rd_data ),
.wclk ( clk ),
.wrst ( rst ),
.wce ( wr_en ),
.we ( wr ),
.waddr ( wr_addr ),
.di ( wr_data )
);
`else
 
reg [7:0] rd_data;
//
// buffer
reg [7:0] buff [0:256];
//
// writing to ram
always @(posedge clk)
begin
if (wr)
buff[wr_addr] <= #1 wr_data;
end
//
// reading from ram
always @(posedge clk or posedge rst)
begin
if (rst)
rd_data <= #1 8'h0;
else if ((wr_addr==rd_addr) & wr & rd_en)
rd_data <= #1 wr_data;
else if (rd_en)
rd_data <= #1 buff[rd_addr];
end
`endif //OC8051_RAM_GENERIC
`endif //OC8051_RAM_VIRTUALSILICON
`endif //OC8051_RAM_XILINX
 
endmodule
//////////////////////////////////////////////////////////////////////
//// ////
//// 8051 internal ram ////
//// ////
//// This file is part of the 8051 cores project ////
//// http://www.opencores.org/cores/8051/ ////
//// ////
//// Description ////
//// 256 bytes two port ram ////
//// ////
//// To Do: ////
//// nothing ////
//// ////
//// Author(s): ////
//// - Simon Teran, simont@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
//
 
// synopsys translate_off
`include "oc8051_timescale.v"
// synopsys translate_on
 
`include "oc8051_defines.v"
 
//
// two port ram
//
module oc8051_ram_256x8_two_bist (
clk,
rst,
rd_addr,
rd_data,
rd_en,
wr_addr,
wr_data,
wr_en,
wr
`ifdef OC8051_BIST
,
scanb_rst,
scanb_clk,
scanb_si,
scanb_so,
scanb_en
`endif
);
 
 
input clk,
wr,
rst,
rd_en,
wr_en;
input [7:0] wr_data;
input [7:0] rd_addr,
wr_addr;
output [7:0] rd_data;
 
`ifdef OC8051_BIST
input scanb_rst;
input scanb_clk;
input scanb_si;
output scanb_so;
input scanb_en;
`endif
 
 
`ifdef OC8051_RAM_XILINX
xilinx_ram_dp xilinx_ram(
// read port
.CLKA(clk),
.RSTA(rst),
.ENA(rd_en),
.ADDRA(rd_addr),
.DIA(8'h00),
.WEA(1'b0),
.DOA(rd_data),
// write port
.CLKB(clk),
.RSTB(rst),
.ENB(wr_en),
.ADDRB(wr_addr),
.DIB(wr_data),
.WEB(wr),
.DOB()
);
defparam
xilinx_ram.dwidth = 8,
xilinx_ram.awidth = 8;
 
`elsif OC8051_RAM_VIRTUALSILICON
 
`elsif OC8051_RAM_ACTEL
oc8051_actel_ram_256x8 oc8051_ram1(
.RWCLK ( clk ),
.RESET ( rst ),
.REN ( rd_en ),
.RADDR ( rd_addr ),
.RD ( rd_data ),
.WEN ( wr ),
.WADDR ( wr_addr ),
.WD ( wr_data )
);
 
`elsif OC8051_RAM_GENERIC
generic_dpram #(8, 8) oc8051_ram1(
.rclk ( clk ),
.rrst ( rst ),
.rce ( rd_en ),
.oe ( 1'b1 ),
.raddr ( rd_addr ),
.do ( rd_data ),
.wclk ( clk ),
.wrst ( rst ),
.wce ( wr_en ),
.we ( wr ),
.waddr ( wr_addr ),
.di ( wr_data )
);
`else
 
reg [7:0] rd_data;
//
// buffer
reg [7:0] buff [0:256];
//
// writing to ram
always @(posedge clk)
begin
if (wr)
buff[wr_addr] <= #1 wr_data;
end
//
// reading from ram
always @(posedge clk or posedge rst)
begin
if (rst)
rd_data <= #1 8'h0;
else if ((wr_addr==rd_addr) & wr & rd_en)
rd_data <= #1 wr_data;
else if (rd_en)
rd_data <= #1 buff[rd_addr];
end
`endif //OC8051_RAM_XILINX
 
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.