---------------------------------------PT13------------------------------------ -- Title: PT13 -- Author: Daniel Ogilvie -- Date: 25-12-2010 ------------------------------------------------------------------------------- -- DESCRIPTION -- This .tdf is the Compact Microprocessor PT13 -- ------------------------------------------------------------------------------- INCLUDE "lpm_counter.inc"; INCLUDE "lpm_constant.inc"; INCLUDE "lpm_compare.inc"; INCLUDE "lpm_ff.inc"; INCLUDE "lpm_add_sub.inc"; INCLUDE "lpm_mux.inc"; SUBDESIGN PT13 ( Ext_SysClk : INPUT; -- Input from 27MHz crystal RESETn : INPUT; -- Power on reset Program_memory_data[7..0] : INPUT; -- Data from Program memory RAM_data_out[7..0] : INPUT; -- Data from RAM memory ROM_A[13..0] : OUTPUT; -- ROM Address bus RAM_A[15..0] : OUTPUT; -- RAM Address bus RAM_data_in[7..0] : OUTPUT; -- Data to RAM read_write : OUTPUT; -- Read/Write to RAM ) VARIABLE En_PC : NODE; PC_increment[13..0] : NODE; Op_Code_en : NODE; Branch : NODE; Branch_inc : NODE; LSB_offset_en : NODE; MSB_offset_en : NODE; PC_update : NODE; AccA_fbk_sel : NODE; AccA_en : NODE; AccA_OFen : NODE; AccB_OFen : NODE; AccA_offset1[7..0] : NODE; AccA_offset2[7..0] : NODE; AccA_add_sub : NODE; AccB_fbk_sel : NODE; AccB_en : NODE; AccB_offset1[7..0] : NODE; AccB_offset2[7..0] : NODE; AccB_add_sub : NODE; AccDP_en : NODE; Addr_offset_en : NODE; IndexOFA : NODE; AccA_carry : NODE; AccB_carry : NODE; Acc_update : NODE; CC_update : NODE; CC_enable : NODE; D7D0_latch : lpm_ff with (lpm_width=4); Carry_latch : lpm_ff with (lpm_width=2); Condition_code[7..0] : NODE; Acc_updateOF : NODE; OF_update : NODE; ImmediateA : NODE; ImmediateB : NODE; ImmediateDP : NODE; ImmediateOFA : NODE; ImmediateOFB : NODE; Memory_address_sel : NODE; read_write : NODE; Write_enable : NODE; SP_write : NODE; SP_enable : NODE; RTS : NODE; SScount : lpm_counter with (lpm_width=4); PC : lpm_add_sub with (lpm_width=14, lpm_representative="signed", lpm_pipeline=1, lpm_direction="add", one_input_is_constant="no"); Nesting : lpm_counter with (lpm_width=2); SP_first : lpm_ff with (lpm_width=14); SP_second : lpm_ff with (lpm_width=14); SP_third : lpm_ff with (lpm_width=14); Op_Code : lpm_ff with (lpm_width=8); PC_offset : lpm_mux with (lpm_width=14, lpm_size=4, lpm_widths=2, lpm_pipeline=0); SP_offset : lpm_mux with (lpm_width=14, lpm_size=16, lpm_widths=4, lpm_pipeline=0); MSB_offset : lpm_ff with (lpm_width=6); LSB_offset : lpm_ff with (lpm_width=8); AccDP : lpm_ff with (lpm_width=8); Addr_offset : lpm_ff with (lpm_width=8); Index_address : lpm_mux with (lpm_width=16, lpm_size=2, lpm_widths=1, lpm_pipeline=0); AccA_fbk : lpm_mux with (lpm_width=8, lpm_size=2, lpm_widths=1, lpm_pipeline=0); AccA : lpm_add_sub with (lpm_width=8, lpm_representative="unsigned", lpm_pipeline=1, one_input_is_constant="no"); AccB_fbk : lpm_mux with (lpm_width=8, lpm_size=2, lpm_widths=1, lpm_pipeline=0); AccB : lpm_add_sub with (lpm_width=8, lpm_representative="unsigned", lpm_pipeline=1, one_input_is_constant="no"); AccA_zero : lpm_compare with (lpm_width=8, lpm_pipeline=0); AccA_zero_define : lpm_constant with (lpm_width=8, lpm_cvalue=0); AccB_zero : lpm_compare with (lpm_width=8, lpm_pipeline=0); AccB_zero_define : lpm_constant with (lpm_width=8, lpm_cvalue=0); BEGIN -- *************************************************************************** -- Test stuff -- *************************************************************************** -- State machine counter, 4 bit SScount.(clock, aclr) = (Ext_SysClk, !RESETn); case SScount.q[3..0] is when 2 => SP_write = GND; En_PC = GND; Memory_address_sel = GND; PC_increment[13..0] = B"00000000000000"; CC_update = GND; Op_Code_en = VCC; -- Latch op code from program memory PC_update = GND; Acc_update = GND; Acc_updateOF = GND; read_write = VCC; MSB_offset_en = GND; LSB_offset_en = GND; OF_update = GND; when 4 => -- If Branch get MSB branch offset address: if immediate get data byte SP_write = GND; Memory_address_sel = GND; CC_update = GND; Op_Code_en = GND; PC_update = GND; Acc_update = GND; Acc_updateOF = GND; read_write = VCC; MSB_offset_en = GND; LSB_offset_en = GND; OF_update = GND; If (Branch_inc or ImmediateA or ImmediateB or ImmediateDP or ImmediateOFA or ImmediateOFB) then En_PC = VCC; -- Enable Program counter PC_increment[13..0] = B"00000000000001"; -- Increment Program counter by '1' else En_PC = GND; PC_increment[13..0] = B"00000000000000"; end if; when 7 => SP_write = GND; En_PC = GND; Memory_address_sel = GND; ACC_update = GND; PC_increment[13..0] = B"00000000000000"; CC_update = GND; Op_Code_en = GND; PC_update = GND; Acc_update = GND; Acc_updateOF = GND; read_write = VCC; LSB_offset_en = GND; If (Branch) then -- If Branch get branch offset address MSB_offset_en = VCC; -- Enable MSB address offset latch OF_update = GND; elsif (ImmediateOFA or ImmediateOFB) then MSB_offset_en = GND; -- Enable MSB address offset latch OF_update = VCC; else MSB_offset_en = GND; OF_update = GND; end if; when 8 => SP_write = GND; CC_update = GND; Op_Code_en = GND; -- Latch op code from program memory PC_update = GND; Acc_update = GND; Acc_updateOF = GND; read_write = VCC; MSB_offset_en = GND; LSB_offset_en = GND; OF_update = GND; If (Branch_inc) then -- If Branch get LSB branch offset address Memory_address_sel = GND; En_PC = VCC; -- Enable Program PC_increment[13..0] = B"00000000000001"; -- Increment Program counter by '1' elsif (ImmediateOFA or ImmediateOFB or IndexOFA) then -- If direct address then address data Memory_address_sel = VCC; En_PC = GND; PC_increment[13..0] = B"00000000000000"; else En_PC = GND; Memory_address_sel = GND; PC_increment[13..0] = B"00000000000000"; end if; when 9 => SP_write = GND; En_PC = GND; PC_increment[13..0] = B"00000000000000"; CC_update = GND; Op_Code_en = GND; PC_update = GND; Acc_update = GND; Acc_updateOF = GND; read_write = VCC; MSB_offset_en = GND; LSB_offset_en = GND; OF_update = GND; If (ImmediateOFA or ImmediateOFB or IndexOFA) then -- If direct address then address data Memory_address_sel = VCC; else Memory_address_sel = GND; end if; when 11 => SP_write = GND; En_PC = GND; Memory_address_sel = GND; PC_increment[13..0] = B"00000000000000"; CC_update = GND; Op_Code_en = GND; PC_update = GND; Acc_update = GND; MSB_offset_en = GND; OF_update = GND; If Write_enable then read_write = GND; else read_write = VCC; end if; If (Branch) then -- If Branch get branch offset address LSB_offset_en = VCC; -- Enable LSB address offset latch Acc_updateOF = GND; elsif (ImmediateOFA or ImmediateOFB or IndexOFA) then LSB_offset_en = GND; Acc_updateOF = VCC; else LSB_offset_en = GND; Acc_updateOF = GND; end if; when 12 => SP_write = GND; En_PC = GND; Memory_address_sel = GND; PC_increment[13..0] = B"00000000000000"; CC_update = GND; Op_Code_en = GND; PC_update = GND; Acc_update = GND; Acc_updateOF = GND; MSB_offset_en = GND; LSB_offset_en = GND; OF_update = GND; If Write_enable then read_write = GND; else read_write = VCC; end if; when 13 => SP_write = GND; En_PC = GND; Memory_address_sel = GND; PC_increment[13..0] = B"00000000000000"; CC_update = GND; Op_Code_en = GND; PC_update = GND; Acc_update = GND; Acc_updateOF = GND; MSB_offset_en = GND; LSB_offset_en = GND; OF_update = GND; If Write_enable then read_write = GND; else read_write = VCC; end if; when 14 => SP_write = VCC; En_PC = GND; Memory_address_sel = GND; PC_increment[13..0] = B"00000000000000"; CC_update = GND; Op_Code_en = GND; PC_update = GND; Acc_update = VCC; Acc_updateOF = GND; read_write = VCC; MSB_offset_en = GND; LSB_offset_en = GND; OF_update = GND; when 15 => SP_write = GND; En_PC = VCC; Memory_address_sel = GND; PC_increment[13..0] = B"00000000000001"; CC_update = VCC; Op_Code_en = GND; PC_update = VCC; Acc_update = GND; Acc_updateOF = GND; read_write = VCC; MSB_offset_en = GND; LSB_offset_en = GND; OF_update = GND; when others => SP_write = GND; En_PC = GND; Memory_address_sel = GND; PC_increment[13..0] = B"00000000000000"; CC_update = GND; Op_Code_en = GND; PC_update = GND; Acc_update = GND; Acc_updateOF = GND; read_write = VCC; MSB_offset_en = GND; LSB_offset_en = GND; OF_update = GND; end case; -- *************************************************************************** -- Program counter PC_offset.(data[][], sel[]) = ((B"00000000000000", B"00000000000001", (MSB_offset.q[5..0],LSB_offset.q[7..0]), PC_increment[13..0]), (RTS,(Branch and PC_update))); PC.(dataa[], datab[], aclr, clken, clock) = (SP_offset.result[13..0], PC_offset.result[13..0], !RESETn, En_PC, Ext_SysClk); Index_address.(data[][], sel[]) = (((AccDP.q[7..0],AccB.result[7..0]),(AccDP.q[7..0],Addr_offset.q[7..0])), IndexOFA); ROM_A[13..0] = PC.result[13..0]; RAM_A[15..0] = Index_address.result[15..0]; -- Stack pointer SP_first.(data[], enable, aclr, clock) = (PC.result[13..0], (SP_write and SP_enable and !Nesting.q[1] and !Nesting.q[0]), !RESETn, Ext_SysClk); SP_second.(data[], enable, aclr, clock) = (PC.result[13..0], (SP_write and SP_enable and !Nesting.q[1] and Nesting.q[0]), !RESETn, Ext_SysClk); SP_third.(data[], enable, aclr, clock) = (PC.result[13..0], (SP_write and SP_enable and Nesting.q[1] and !Nesting.q[0]), !RESETn, Ext_SysClk); SP_offset.(data[][], sel[]) = ((B"00000000000000", SP_third.q[13..0], B"00000000000000", PC.result[13..0], B"00000000000000", SP_second.q[13..0], B"00000000000000", PC.result[13..0], B"00000000000000", SP_first.q[13..0], B"00000000000000", PC.result[13..0], B"00000000000000", PC.result[13..0], B"00000000000000", PC.result[13..0]), (Nesting.q[1], Nesting.q[0], RTS, (Branch and PC_update))); -- Subroutine nesting counter Nesting.(clock, cnt_en, updown, aclr) = (Ext_SysClk, ((Branch and SP_enable and PC_update) or (RTS and PC_update)), (Branch and SP_enable), !RESETn); -- Latch Op Code from program memory Op_Code.(data[], enable, aclr, clock) = (Program_memory_data[7..0], Op_Code_en, !RESETn, Ext_SYSClk); -- Latch MSB of branch offset address MSB_offset.(data[], enable, aclr, clock) = (Program_memory_data[5..0], MSB_offset_en, !RESETn, Ext_SYSClk); -- Latch MSB of branch offset address LSB_offset.(data[], enable, aclr, clock) = (Program_memory_data[7..0], LSB_offset_en, !RESETn, Ext_SYSClk); -- *************************************************************************** -- Decode Op Codes case Op_Code.q[7..4] is when H"0" => -- NOP case Op_Code.q[3..0] is when 0 => -- NOP RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; CC_enable = GND; AccA_OFen = GND; AccB_OFen = GND; AccB_offset1[] = B"00000000"; AccB_offset2[] = B"00000000"; AccA_en = GND; AccB_fbk_sel = GND; AccB_add_sub = GND; AccB_en = GND; AccDP_en = GND; Addr_offset_en = GND; IndexOFA = GND; Branch = GND; Branch_inc = GND; Write_enable = GND; RAM_data_in[7..0] = B"00000000"; when others => RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; CC_enable = GND; AccA_OFen = GND; AccB_OFen = GND; AccB_offset1[] = B"00000000"; AccB_offset2[] = B"00000000"; AccA_en = GND; AccB_fbk_sel = GND; AccB_add_sub = GND; AccB_en = GND; AccDP_en = GND; Addr_offset_en = GND; IndexOFA = GND; Write_enable = GND; RAM_data_in[7..0] = B"00000000"; end case; when H"1" => -- Load and Store instructions case Op_Code.q[3..0] is when 0 => -- LDI A (Load AccA Immediate) RTS = GND; ImmediateA = VCC; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; IndexOFA = GND; AccA_en = VCC; AccB_en = GND; AccDP_en = GND; AccA_offset1[] = Program_memory_data[7..0]; AccA_offset2[] = B"00000000"; AccA_carry = GND; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 1 => -- LDI B (Load AccB Immediate) RTS = GND; ImmediateA = GND; ImmediateB = VCC; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; IndexOFA = GND; AccA_en = GND; AccB_en = VCC; AccDP_en = GND; AccB_offset1[] = Program_memory_data[7..0]; AccB_offset2[] = B"00000000"; AccA_carry = Carry_latch.q[0]; AccB_carry = GND; CC_enable = VCC; AccB_fbk_sel = VCC; AccB_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 2 => -- LDI DP (Load DP Immediate) RTS = GND; IndexOFA = GND; AccA_en = GND; AccB_en = GND; AccDP_en = VCC; Branch = GND; Branch_inc = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = VCC; ImmediateOFA = GND; ImmediateOFB = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; when 8 => -- LDD A (Load A Direct) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = VCC; ImmediateOFB = GND; IndexOFA = GND; Branch = GND; Branch_inc = GND; Addr_offset_en = VCC; AccA_OFen = VCC; AccA_en = VCC; AccB_en = GND; AccDP_en = GND; AccA_offset1[] = RAM_data_out[7..0]; AccA_offset2[] = B"00000000"; AccA_carry = GND; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Write_enable = GND; when 9 => -- LDD B (Load B Direct) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = VCC; IndexOFA = GND; Branch = GND; Branch_inc = GND; Addr_offset_en = VCC; AccB_OFen = VCC; AccA_en = GND; AccB_en = VCC; AccDP_en = GND; AccB_offset1[] = RAM_data_out[7..0]; AccB_offset2[] = B"00000000"; AccA_carry = Carry_latch.q[0]; AccB_carry = GND; CC_enable = VCC; AccB_fbk_sel = VCC; AccB_add_sub = GND; Write_enable = GND; when H"C" => -- LDRI (Load A Indexed) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; IndexOFA = VCC; Addr_offset_en = GND; AccA_OFen = VCC; AccA_en = VCC; AccB_en = GND; AccDP_en = GND; AccA_offset1[] = RAM_data_out[7..0]; AccA_offset2[] = B"00000000"; AccA_carry = GND; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Write_enable = GND; when others => RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; CC_enable = GND; AccA_OFen = GND; AccB_OFen = GND; AccB_offset1[] = B"00000000"; AccB_offset2[] = B"00000000"; AccA_en = GND; AccB_fbk_sel = GND; AccB_add_sub = GND; AccB_en = GND; AccDP_en = GND; Addr_offset_en = GND; IndexOFA = GND; Write_enable = GND; RAM_data_in[7..0] = B"00000000"; end case; when H"2" => -- Load and Store instructions case Op_Code.q[3..0] is when 4 => -- STR A (Store AccA into RAM location DP,OF) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = VCC; ImmediateOFB = GND; IndexOFA = GND; Branch = GND; Branch_inc = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = VCC; RAM_data_in[7..0] = AccA.result[7..0]; Write_enable = VCC; when 5 => -- STR B (Store AccB into RAM location DP,OF) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = VCC; Branch = GND; Branch_inc = GND; IndexOFA = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = VCC; RAM_data_in[7..0] = AccB.result[7..0]; Write_enable = VCC; when others => RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; CC_enable = GND; AccA_OFen = GND; AccB_OFen = GND; AccB_offset1[] = B"00000000"; AccB_offset2[] = B"00000000"; AccA_en = GND; AccB_fbk_sel = GND; AccB_add_sub = GND; AccB_en = GND; AccDP_en = GND; Addr_offset_en = GND; IndexOFA = GND; Write_enable = GND; RAM_data_in[7..0] = B"00000000"; end case; when H"5" => -- Arithmetic instructions case Op_Code.q[3..0] is when 0 => -- ADD A (ADD AccA Immediate) RTS = GND; ImmediateA = VCC; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = Program_memory_data[7..0]; AccA_offset2[] = B"00000000"; AccA_fbk_sel = GND; AccA_add_sub = GND; AccA_carry = AccA.cout; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; Addr_offset_en = GND; Write_enable = GND; when 1 => -- ADD B (ADD AccB Immediate) RTS = GND; ImmediateA = GND; ImmediateB = VCC; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccB_en = VCC; AccB_offset1[] = Program_memory_data[7..0]; AccB_offset2[] = B"00000000"; AccA_carry = Carry_latch.q[0]; AccB_carry = AccB.cout; CC_enable = VCC; AccB_fbk_sel = GND; AccB_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 4 => -- ADD A,B (AccA + AccB) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = AccB.result[7..0]; AccA_offset2[] = B"00000000"; AccA_carry = AccA.cout; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = GND; AccA_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 8 => -- SUB A (SUB AccA Immediate) RTS = GND; ImmediateA = VCC; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = Program_memory_data[7..0]; AccA_offset2[] = B"00000000"; AccA_carry = AccA.cout; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = GND; AccA_add_sub = VCC; Addr_offset_en = GND; Write_enable = GND; when 9 => -- SUB B (SUB AccB Immediate) RTS = GND; ImmediateA = GND; ImmediateB = VCC; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccB_en = VCC; AccB_offset1[] = Program_memory_data[7..0]; AccB_offset2[] = B"00000000"; AccA_carry = Carry_latch.q[0]; AccB_carry = AccB.cout; CC_enable = VCC; AccB_fbk_sel = GND; AccB_add_sub = VCC; Addr_offset_en = GND; Write_enable = GND; when H"C" => -- SUB A,B (AccA - AccB) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = AccB.result[7..0]; AccA_offset2[] = B"00000000"; AccA_carry = AccA.cout; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = GND; AccA_add_sub = VCC; Addr_offset_en = GND; Write_enable = GND; when others => RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = GND; AccB_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; end case; when H"6" => -- Logical instructions case Op_Code.q[3..0] is when 0 => -- AND A (AND AccA Immediate) RTS = GND; ImmediateA = VCC; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = (Program_memory_data[7..0] and AccA.result[7..0]); AccA_offset2[] = B"00000000"; AccA_carry = GND; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 1 => -- AND B (AND AccB Immediate) RTS = GND; ImmediateA = GND; ImmediateB = VCC; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccB_en = VCC; AccB_offset1[] = (Program_memory_data[7..0] and AccB.result[7..0]); AccB_offset2[] = B"00000000"; AccA_carry = Carry_latch.q[0]; AccB_carry = GND; CC_enable = VCC; AccB_fbk_sel = VCC; AccB_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 4 => -- AND A,B (AccA AND AccB) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = (AccA.result[7..0] and AccB.result[7..0]); AccA_offset2[] = B"00000000"; AccA_carry = GND; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 8 => -- OR A (OR AccA Immediate) RTS = GND; ImmediateA = VCC; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = (Program_memory_data[7..0] or AccA.result[7..0]); AccA_offset2[] = B"00000000"; AccA_carry = GND; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 9 => -- OR B (OR AccB Immediate) RTS = GND; ImmediateA = GND; ImmediateB = VCC; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccB_en = VCC; AccB_offset1[] = (Program_memory_data[7..0] or AccB.result[7..0]); AccB_offset2[] = B"00000000"; AccA_carry = Carry_latch.q[0]; AccB_carry = GND; CC_enable = VCC; AccB_fbk_sel = VCC; AccB_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when H"C" => -- OR A,B (AccA OR AccB) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = (AccA.result[7..0] or AccB.result[7..0]); AccA_offset2[] = B"00000000"; AccA_carry = GND; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when others => RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = GND; AccB_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; end case; when H"7" => -- Logical instructions case Op_Code.q[3..0] is when 0 => -- XOR A (XOR AccA Immediate) RTS = GND; ImmediateA = VCC; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = (Program_memory_data[7..0] xor AccA.result[7..0]); AccA_offset2[] = B"00000000"; AccA_carry = GND; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 1 => -- XOR B (XOR AccB Immediate) RTS = GND; ImmediateA = GND; ImmediateB = VCC; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccB_en = VCC; AccB_offset1[] = (Program_memory_data[7..0] xor AccB.result[7..0]); AccB_offset2[] = B"00000000"; AccA_carry = Carry_latch.q[0]; AccB_carry = GND; CC_enable = VCC; AccB_fbk_sel = VCC; AccB_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 4 => -- XOR A,B (AccA XOR AccB) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = (AccA.result[7..0] xor AccB.result[7..0]); AccA_offset2[] = B"00000000"; AccA_carry = GND; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 8 => -- LSL A (Logical shift left AccA) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = (AccA.result[6..0],0); AccA_offset2[] = B"00000000"; AccA_carry = D7D0_latch.q[1]; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 9 => -- LSL B (Logical shift left AccB) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccB_en = VCC; AccB_offset1[] = (AccB.result[6..0],0); AccB_offset2[] = B"00000000"; AccA_carry = Carry_latch.q[0]; AccB_carry = D7D0_latch.q[3]; CC_enable = VCC; AccB_fbk_sel = VCC; AccB_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when H"C" => -- LSR A (Logical shift right AccA) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = (0,AccA.result[7..1]); AccA_offset2[] = B"00000000"; AccA_carry = D7D0_latch.q[0]; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when H"D" => -- LSR B (Logical shift right AccB) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccB_en = VCC; AccB_offset1[] = (0,AccB.result[7..1]); AccB_offset2[] = B"00000000"; AccA_carry = Carry_latch.q[0]; AccB_carry = D7D0_latch.q[2]; CC_enable = VCC; AccB_fbk_sel = VCC; AccB_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when others => RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = GND; AccB_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; end case; when H"8" => -- Rotate instructions case Op_Code.q[3..0] is when 0 => -- ASR A (Arithmetic shift right AccA) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = (AccA.result[7],AccA.result[7..1]); AccA_offset2[] = B"00000000"; AccA_carry = D7D0_latch.q[0]; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 1 => -- ASR B (Arithmetic shift right AccB) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccB_en = VCC; AccB_offset1[] = (AccB.result[7],AccB.result[7..1]); AccB_offset2[] = B"00000000"; AccA_carry = Carry_latch.q[0]; AccB_carry = D7D0_latch.q[2]; CC_enable = VCC; AccB_fbk_sel = VCC; AccB_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 4 => -- ROL A (Rotate left AccA) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = (AccA.result[6..0],Carry_latch.q[0]); AccA_offset2[] = B"00000000"; AccA_carry = D7D0_latch.q[1]; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 5 => -- ROL B (Rotate left AccB) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccB_en = VCC; AccB_offset1[] = (AccB.result[6..0],Carry_latch.q[1]); AccB_offset2[] = B"00000000"; AccA_carry = Carry_latch.q[0]; AccB_carry = D7D0_latch.q[3]; CC_enable = VCC; AccB_fbk_sel = VCC; AccB_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 8 => -- ROR A (Rotate right AccA) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccA_offset1[] = (Carry_latch.q[0],AccA.result[7..1]); AccA_offset2[] = B"00000000"; AccA_carry = D7D0_latch.q[0]; AccB_carry = Carry_latch.q[1]; CC_enable = VCC; AccA_fbk_sel = VCC; AccA_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when 9 => -- ROR B (Rotate right AccB) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; AccB_en = VCC; AccB_offset1[] = (Carry_latch.q[1],AccB.result[7..1]); AccB_offset2[] = B"00000000"; AccA_carry = Carry_latch.q[0]; AccB_carry = D7D0_latch.q[2]; CC_enable = VCC; AccB_fbk_sel = VCC; AccB_add_sub = GND; Addr_offset_en = GND; Write_enable = GND; when others => RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; Branch = GND; Branch_inc = GND; SP_enable = GND; AccA_en = GND; AccB_en = GND; Addr_offset_en = GND; Write_enable = GND; end case; when H"E" => -- Branch instructions case Op_Code.q[3..0] is when 0 => -- BCC A (Branch if AccA carry clear) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; Branch_inc = VCC; If !Condition_code[1] then Branch = VCC; else Branch = GND; end if; when 1 => -- BCC B (Branch if AccB carry clear) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; Branch_inc = VCC; If !Condition_code[5] then Branch = VCC; else Branch = GND; end if; when 4 => -- BCS A (Branch if AccA carry set) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; Branch_inc = VCC; If Condition_code[1] then Branch = VCC; else Branch = GND; end if; when 5 => -- BCS B (Branch if AccB carry set) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; Branch_inc = VCC; If Condition_code[5] then Branch = VCC; else Branch = GND; end if; when 8 => -- BEQ A (Branch if AccA = $00) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; Branch_inc = VCC; If Condition_code[0] then Branch = VCC; else Branch = GND; end if; when 9 => -- BEQ B (Branch if AccB = $00) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; Branch_inc = VCC; If Condition_code[4] then Branch = VCC; else Branch = GND; end if; when H"C" => -- BNE A (Branch if AccA != $00) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; Branch_inc = VCC; If !Condition_code[0] then Branch = VCC; else Branch = GND; end if; when H"D" => -- BNE B (Branch if AccB != $00) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; Branch_inc = VCC; If !Condition_code[4] then Branch = VCC; else Branch = GND; end if; when others => RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; Branch = GND; Branch_inc = GND; end case; when H"F" => -- Branch instructions case Op_Code.q[3..0] is when H"C" => -- BRA (Branch always) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; SP_enable = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; Branch_inc = VCC; Branch = VCC; Branch_inc = GND; when H"D" => -- BSR (Branch to subroutine) RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = GND; Write_enable = GND; SP_enable = VCC; Branch = VCC; Branch_inc = VCC; when H"E" => -- RTS (Return from subroutine) RTS = VCC; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Write_enable = GND; Addr_offset_en = GND; SP_enable = GND; Branch = GND; Branch_inc = GND; when others => RTS = GND; ImmediateA = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; AccA_en = GND; AccB_en = GND; AccDP_en = GND; CC_enable = GND; Addr_offset_en = GND; SP_enable = GND; Write_enable = GND; Branch = GND; Branch_inc = GND; end case; when others => RTS = GND; SP_enable = GND; Branch = GND; Branch_inc = GND; AccA_en = VCC; AccB_en = GND; AccDP_en = GND; AccA_fbk_sel = GND; ImmediateA = GND; AccA_OFen = GND; AccB_OFen = GND; AccB_fbk_sel = GND; AccB_offset1[] = B"00000000"; AccB_offset2[] = B"00000000"; AccB_add_sub = GND; CC_enable = GND; ImmediateB = GND; ImmediateDP = GND; ImmediateOFA = GND; ImmediateOFB = GND; read_write = VCC; Addr_offset_en = GND; Write_enable = GND; RAM_data_in[7..0] = B"00000000"; end case; -- *************************************************************************** -- Accumulator A AccA_fbk.(data[][], sel[]) = ((AccA_offset2[7..0], AccA.result[7..0]), AccA_fbk_sel); AccA.(dataa[], datab[], add_sub, aclr, clken, clock) = (AccA_fbk.result[7..0], AccA_offset1[7..0], !AccA_add_sub, !RESETn, ((AccA_en and ACC_update) or (AccA_OFen and ACC_updateOF)), Ext_SysClk); AccA_zero.(dataa[], datab[]) = (AccA.result[7..0], AccA_zero_define.result[]); -- *************************************************************************** -- Accumulator B AccB_fbk.(data[][], sel[]) = ((AccB_offset2[7..0], AccB.result[7..0]), AccB_fbk_sel); AccB.(dataa[], datab[], add_sub, aclr, clken, clock) = (AccB_fbk.result[7..0], AccB_offset1[7..0], !AccB_add_sub, !RESETn, ((AccB_en and ACC_update) or (AccB_OFen and ACC_updateOF)), Ext_SysClk); AccB_zero.(dataa[], datab[]) = (AccB.result[7..0], AccB_zero_define.result[]); -- *************************************************************************** -- Store D7/D0 bits of accumulator for rotate and ASR instructions D7D0_latch.(data[], enable, aclr, clock) = ((AccB.result[7],AccB.result[0],AccA.result[7],AccA.result[0]), Op_Code_en, !RESETn, Ext_SysClk); Carry_latch.(data[], enable, aclr, clock) = ((AccB_carry, AccA_carry), (CC_update and CC_enable), !RESETn, Ext_SysClk); Condition_code[7..0] = (GND, GND, Carry_latch.q[1], AccB_zero.aeb, GND, GND, Carry_latch.q[0], AccA_zero.aeb); -- *************************************************************************** -- Data Page register AccDP.(data[], aclr, enable, clock) = (Program_memory_data[7..0], !RESETn, (AccDP_en and ACC_update), Ext_SysClk); -- *************************************************************************** -- Address offset register Addr_offset.(data[], aclr, enable, clock) = (Program_memory_data[7..0], !RESETn, (Addr_offset_en and OF_update), Ext_SysClk); -- *************************************************************************** END;