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 |