diff --git a/Makefile.files b/Makefile.files index 21a641e..fa1526d 100644 --- a/Makefile.files +++ b/Makefile.files @@ -1,4 +1,4 @@ VHDL_PKG += src/cpupkg.vhd VHDL_TB += src/TBRechner.vhd VHDL_SRC += src/RegFile.vhd src/CPU.vhd src/MemInterface.vhd src/antibeat_device.vhd src/FetchDecode.vhd src/ALU.vhd src/RAM.vhd -VHDL_SRC += src/SOC.vhd src/Steuerwerk.vhd src/Rechner.vhd +VHDL_SRC += src/SOC.vhd src/Steuerwerk.vhd src/MemGuard.vhd src/MMIO_Uart.vhd src/clkDivider.vhd src/ClkEnable.vhd src/MemoryMapper.vhd diff --git a/UCF/xc5vlx110t-3-ff1136.ucf b/UCF/xc5vlx110t-3-ff1136.ucf new file mode 100644 index 0000000..e290ccf --- /dev/null +++ b/UCF/xc5vlx110t-3-ff1136.ucf @@ -0,0 +1,14 @@ +NET idRS232 LOC="AG15"; # Bank 4, Vcco=3.3V, No DCI +NET odRS232 LOC="AG20"; # Bank 4, Vcco=3.3V, No DCI +NET reset LOC="E9"; +NET ic200MhzClk LOC = L19 | IOSTANDARD = LVTTL; #200Mhz Clk +NET clk LOC = "AH15"; #100Mhz clk + +NET data_print_2(0) LOC="AE24" | IOSTANDARD = SSTL18_II_DCI; +NET data_print_2(1) LOC="AD24" | IOSTANDARD = SSTL18_II_DCI; +NET data_print_2(2) LOC="AD25" | IOSTANDARD = SSTL18_II_DCI; +NET data_print_2(3) LOC="G16" | IOSTANDARD = LVTTL; +NET data_print_2(4) LOC="AD26" | IOSTANDARD = SSTL18_II_DCI; +NET data_print_2(5) LOC="G15" | IOSTANDARD = LVTTL; +NET data_print_2(6) LOC="L18" | IOSTANDARD = LVTTL; +NET data_print_2(7) LOC="H18" | IOSTANDARD = LVTTL; \ No newline at end of file diff --git a/asm/bootloader.s b/asm/bootloader.s new file mode 100644 index 0000000..613caa5 --- /dev/null +++ b/asm/bootloader.s @@ -0,0 +1,6 @@ +start: + + + + + diff --git a/asm/test-jmc.s b/asm/test-jmc.s new file mode 100644 index 0000000..41cf4e6 --- /dev/null +++ b/asm/test-jmc.s @@ -0,0 +1,43 @@ +start: +lui $0, 0 +lui $1, 35 +lui $2, 36 +jmc print +sto $1, 65521 +jmc print +jmp end +print: +add $30, $31, $0 +sto $30, 65521 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +sto $30, 65521 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +sto $30, 65521 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +shr $30, $30, $0 +sto $30, 65521 +sto $1, 65521 +ret +sto $2, 65521 +end: +hlt diff --git a/asm/test-read-uart.s b/asm/test-read-uart.s new file mode 100644 index 0000000..b836e9a --- /dev/null +++ b/asm/test-read-uart.s @@ -0,0 +1,60 @@ +start: +loa $1, 65520 +jmc print +jmc wait +jmp start +print: +add $20, $1, $0 +sto $20, 65521 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +sto $20, 65521 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +sto $20, 65521 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +shr $20, $20, $0 +sto $20, 65521 +ret +wait: +lui $10, 600 +shl $10, $10, $0 +shl $10, $10, $0 +shl $10, $10, $0 +shl $10, $10, $0 +shl $10, $10, $0 +shl $10, $10, $0 +shl $10, $10, $0 +shl $10, $10, $0 +shl $10, $10, $0 +shl $10, $10, $0 +shl $10, $10, $0 +shl $10, $10, $0 +shl $10, $10, $0 +shl $10, $10, $0 +shl $10, $10, $0 +lui $11, 1 +loop: +sub $10, $10, $11 +jpz endloop +jmp loop +endloop: +ret diff --git a/asm/uart-test.s b/asm/uart-test.s new file mode 100644 index 0000000..f6d7f9a --- /dev/null +++ b/asm/uart-test.s @@ -0,0 +1,7 @@ +start: +lui $1, 71 +loop: +sto $1, 65521 + +jmp loop +hlt diff --git a/scripts/asm.pl b/scripts/asm.pl index 395462c..e1a4193 100755 --- a/scripts/asm.pl +++ b/scripts/asm.pl @@ -6,7 +6,7 @@ my $nr_instr_bytes = 4; my $nr_opcode_bits = 6; my $nr_reg_bits = 5; -my $startaddr = 0; +my $startaddr = -1; # mnemonnic to opcode conversion my %opcodes = ( @@ -26,6 +26,8 @@ my %opcodes = ( 'jpc' => 0x0D, 'jmp' => 0x0E, 'lui' => 0x0F, + 'jmc' => 0x10, + 'ret' => 0x11, 'hlt' => 0x3F ); @@ -304,6 +306,14 @@ while ( my $line = <$src> ) { elsif ( $INSTR eq "jpc" ) { $label = $REST; } + elsif ( $INSTR eq "jmc" ) { + $label = $REST; + + my $dst = 31; + $dst = $dst << 21; + $opc = $opc | $dst; + + } elsif ( $INSTR eq "jmp" ) { $label = $REST; } @@ -326,6 +336,12 @@ while ( my $line = <$src> ) { ; } } + elsif ( $INSTR eq "ret" ) { + my $op1=31; + $op1 = $op1 << 16; + $opc = $opc | $op1; + + } elsif ( $INSTR =~ /^(.*):$/ ) { $labels{$1} = $addr; $addr--; @@ -345,7 +361,10 @@ while ( my $line = <$src> ) { $instruction->{opc} = $opc; $instruction->{comment} = $line; $instruction->{label} = $label; - + + if ($line =~/jmc/) { + print "-" .$instruction->{label}."-\n"; + } push( @instructions, $instruction ); } diff --git a/src/ALU.vhd b/src/ALU.vhd index 342397c..c9eb1f2 100644 --- a/src/ALU.vhd +++ b/src/ALU.vhd @@ -53,7 +53,7 @@ begin sdOp1 <= '0' & idOperand1; sdOp2 <= '0' & idOperand2; - process (sdOp1, sdOp2, idCarryIn, icOperation, idImmidiate) + process (sdOp1, sdOp2, idCarryIn, icOperation, idImmidiate, idOperand1) begin if (icOperation = shl) then sdTempResult <= sdOp1(31 downto 0) & "0"; @@ -65,7 +65,7 @@ begin sdTempResult <= (others => '-'); elsif (icOperation = loa) then - sdTempResult <= sdOp2; + sdTempResult <= '0' & idImmidiate; elsif (icOperation = li) then sdTempResult <= '0' & idImmidiate; elsif (icOperation = add) then diff --git a/src/CPU.vhd b/src/CPU.vhd index 9e884ed..8b55aa9 100644 --- a/src/CPU.vhd +++ b/src/CPU.vhd @@ -57,7 +57,10 @@ architecture Behavioral of CPU is ocLoadInstr : out std_logic; --! load instruction control signal ocNextPC : out std_logic; --! increment pc ocAddrSel : out std_logic; --! pc on addressbus - ocJump : out std_logic --! do a ocJump + ocJump : out std_logic; --! do a ocJump + ocPCregister : out std_logic; --! put PC to register File + ocUsePC : out std_logic; --! use Register to fill in the PC + ocLoad : out std_logic --! put databus to ALU immediate port ); end component; @@ -71,6 +74,8 @@ architecture Behavioral of CPU is odRegA : out DATA; odRegB : out DATA; + icPC : in std_logic; -- select PC as input to RegisterFile + idPC : in DATA; icRegINsel : in std_logic_vector(4 downto 0); @@ -110,6 +115,9 @@ architecture Behavioral of CPU is icLoadInstr : in std_logic; icJump : in std_logic; icNextPC : in std_logic; + idPC : in ADDRESS; + icUsePC : in std_logic; + odPC : out ADDRESS; odAddress : out ADDRESS; odImmidiate : out DATA; @@ -134,7 +142,16 @@ architecture Behavioral of CPU is idAddressCPU : in ADDRESS ); end component; - + + + signal sdPC : DATA; + signal scPCregister : std_logic; + + signal scUsePC : std_logic; + signal sdPCfetch : ADDRESS; + + signal scLoad : std_logic; + signal scOpCode : optype; signal sdCarryRF : std_logic; signal sdZeroRF : std_logic; @@ -148,10 +165,10 @@ architecture Behavioral of CPU is signal sdAkkuRes : DATA; signal sdCarryAkku : std_logic; signal sdZeroAkku : std_logic; - signal sdDataOut : DATA; signal sdDataIn : DATA; signal sdAddress : ADDRESS; signal sdImmidiate : DATA; + signal sdImmidiateALU: DATA; signal sdRegAsel : std_logic_vector(4 downto 0); signal sdRegBsel : std_logic_vector(4 downto 0); signal sdRegINsel : std_logic_vector(4 downto 0); @@ -172,7 +189,10 @@ begin ocLoadInstr => scLoadInstr, ocNextPC => scNextPC, ocAddrSel => scAddrSel, - ocJump => scJump + ocJump => scJump, + ocPCregister => scPCregister, + ocUsePC => scUsePC, + ocLoad => scLoad ); RF: RegFile PORT MAP( @@ -183,6 +203,9 @@ begin icRegBsel => sdRegBsel, icRegINsel => sdRegINsel, + icPC => scPCregister, + idPC => sdPC, + idDataIn => sdAkkuRes, idCarryIn => sdCarryAkku, idZeroIn => sdZeroAkku, @@ -198,7 +221,7 @@ begin Calc : ALU Port MAP( idOperand1 => sdRegA, idOperand2 => sdRegB, - idImmidiate => sdImmidiate, + idImmidiate => sdImmidiateALU, idCarryIn => sdCarryRF, odResult => sdAkkuRes, @@ -208,6 +231,8 @@ begin icOperation => scOpCode ); + + sdPC(31 downto 16) <= (others=>'0'); FaD : FetchDecode PORT MAP( iClk => iClk, iReset => iReset, @@ -216,8 +241,11 @@ begin icAddrSel => scAddrSel, icLoadInstr => scLoadInstr, icJump => scJump, - icNextPC => scNextPC, + icNextPC => scNextPC, + odPC => sdPC(15 downto 0), + idPC => sdRegA(15 downto 0), + icUsePC => scUsePC, odAddress => sdAddress, odImmidiate => sdImmidiate, odRegAsel => sdRegAsel, @@ -239,6 +267,9 @@ begin idAddressCPU => sdAddress ); - + + sdImmidiateALU <= bdData when scLoad='1' else + sdImmidiate; + end Behavioral; diff --git a/src/ClkEnable.vhd b/src/ClkEnable.vhd new file mode 100644 index 0000000..9471473 --- /dev/null +++ b/src/ClkEnable.vhd @@ -0,0 +1,64 @@ +-------------------------------------------------------------------------------- +-- Entity: ClkEnable +-------------------------------------------------------------------------------- +-- Copyright ... 2011 +-- Filename : ClkEnable.vhd +-- Creation date : 2012-04-06 +-- Author(s) : marcel eckert (eckert@hsu-hh.de) +-------------------------------------------------------------------------------- +--! @file +--! @brief Implements a generic ClkEnable generator +-------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + + +--! brief Implements a generic ClkEnable generator + +--! detailed Implements a generic ClkEnable generator. Based on an input frequency +--! , an output enable (1 period) is generated every +--! periods + +entity clkEnable is + generic( + GEN_FreqIn_Hz : integer := 200000000; --! signal description input clock frequency in Hz for + GEN_FreqOut_Hz : integer := 100000000 --! signal description output clock frequency in Hz for + ); + port ( + iClkin : in STD_LOGIC; --! signal description input clock + iReset : in STD_LOGIC; --! signal description synchronous reset (should be tied to '0') + oeClkEn : out STD_LOGIC --! signal description output clockEnable + ); +end clkEnable; + +architecture Behavioral of clkEnable is + constant cLimit : integer := GEN_FreqIn_Hz / GEN_FreqOut_Hz; + signal sCounter : integer range 0 to (cLimit-1) := 0; + signal seClkEn : STD_LOGIC := '1'; +begin + + process (iClkIn) + begin + if (rising_edge(iClkIn)) then + if (iReset = '1') then + sCounter <= 0; + seClkEn <= '1'; + + elsif (sCounter = (cLimit-1)) then + sCounter <= 0; + seClkEn <= '1'; + + else + sCounter <= sCounter + 1; + seClkEn <= '0'; + end if; + + end if; + + end process; + + oeClkEn <= seClkEn; + +end Behavioral; + diff --git a/src/FetchDecode.vhd b/src/FetchDecode.vhd index 5a3e1cd..17cc06f 100644 --- a/src/FetchDecode.vhd +++ b/src/FetchDecode.vhd @@ -42,8 +42,10 @@ entity FetchDecode is icAddrSel : in std_logic; icLoadInstr : in std_logic; icJump : in std_logic; - icNextPC : in std_logic; - + icNextPC : in std_logic; + odPC : out ADDRESS; + idPC : in ADDRESS; + icUsePC : in std_logic; odAddress : out ADDRESS; odImmidiate : out DATA; odRegAsel : out std_logic_vector(4 downto 0); @@ -66,7 +68,7 @@ architecture Behavioral of FetchDecode is signal scOp, scOp_next : OPTYPE; begin - Transition: process(idData, sdImmidate, icLoadInstr, icJump, icNextPC, sdAdr, sdPC, scOp, sdRegAsel, sdRegBsel, sdRegINsel) + Transition: process(idData, sdImmidate, icLoadInstr, icJump, icNextPC, sdAdr, sdPC, scOp, sdRegAsel, sdRegBsel, sdRegINsel, icUsePC, idPC) begin -- defaults sdAdr_next <= sdAdr; @@ -80,7 +82,7 @@ begin --! ISA Definition if (icLoadInstr = '1') then - sdAdr_next <= "0000" & idData(11 downto 0); + sdAdr_next <= idData(15 downto 0); sdImmidiate_next <= "0000000000000000" & idData(15 downto 0); sdRegINsel_next <= idData(25 downto 21); sdRegAsel_next <= idData(20 downto 16); @@ -102,11 +104,17 @@ begin when "001100" => scOp_next <= jpz; when "001101" => scOp_next <= jpc; when "001110" => scOp_next <= jmp; - when "001111" => scOP_next <= li; + when "001111" => scOP_next <= li; + when "010000" => scOp_next <= jmc; + when "010001" => scOp_next <= ret; when others => scOp_next <= hlt; end case; end if; - + + if (icUsePC = '1') then + sdPC_next <= idPC; + end if; + if (icJump = '1') then sdPC_next <= sdAdr; @@ -114,8 +122,9 @@ begin if (icNextPC = '1') then sdPC_next <= sdPC + '1'; - end if; + + end process; @@ -145,9 +154,12 @@ begin end process; -- Output - odAddress <= sdAdr when icAddrSel = '0' and icLoadInstr = '0' else - sdAdr_next when icAddrSel = '0' and icLoadInstr = '1' else - sdPC; -- addr_sel = '1' + odAddress <= idPC when icUsePC = '1' else + sdAdr when icAddrSel = '0' and icLoadInstr = '0' else + sdAdr_next when icAddrSel = '0' and icLoadInstr = '1' else + sdPC; -- addr_sel = '1' + + odPC <= sdPC; ocOperation <= scOp when icLoadInstr = '0' else scOp_next; diff --git a/src/MMIO_Uart.vhd b/src/MMIO_Uart.vhd new file mode 100644 index 0000000..d2ba9a2 --- /dev/null +++ b/src/MMIO_Uart.vhd @@ -0,0 +1,283 @@ +------------------------------------------------------- +--! @file +--! @brief +--! @author Dominik Meyer +--! @email dmeyer@hsu-hh.de +--! @date 2013-07-18 +------------------------------------------------------- + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; + +library work; +use work.cpupkg.all; + +entity MMIO_Uart is + generic ( + GEN_start : std_logic_vector(15 downto 0) := x"FFF0"; + GEN_SysClockinHz : integer := 100000000; + GEN_Baudrate : integer := 57600; + GEN_HasExternBaudLimit : boolean := true + ); + port ( + + odRS232 : out std_logic; + idRS232 : in std_logic; + + ocInterrupt : out std_logic; --! high if data is available + + odDebug : out std_logic_vector(7 downto 0); + + + iClk : in std_logic; + iReset : in std_logic; + bdData : inout DATA; --! connection to databus + idAddress : in ADDRESS; --! connection to addressbus + icEnable : in std_logic; --! enable or disable RAM + icRnotW : in std_logic --! read/write control + ); +end MMIO_Uart; + +architecture arch of MMIO_Uart is + + component UART + generic ( + GEN_SysClockinHz : integer; + GEN_Baudrate : integer; + GEN_HasExternBaudLimit : boolean + ); + port ( + iSysClk : in std_logic; + ieClkEn : in std_logic; + iReset : in std_logic; + icBaudLExt : in integer; + icSend : in std_logic; + idDataSend : in std_logic_vector ( 7 downto 0 ); + ocSEmpty : out std_logic; + ocSFull : out std_logic; + ocSAlmostE : out std_logic; + ocSAlmostF : out std_logic; + odTransmit : out std_logic; + odDataRcvd : out std_logic_vector ( 7 downto 0 ); + ocREmpty : out std_logic; + ocRFull : out std_logic; + ocRAlmostE : out std_logic; + ocRAlmostF : out std_logic; + icRReadEn : in std_logic; + idReceive : in std_logic + ); + end component; + + + + signal srTransmit : std_logic_vector(31 downto 0); + signal srReceive : std_logic_vector(31 downto 0); + signal srStatus : std_logic_vector(31 downto 0); + signal srBaud : std_logic_vector(31 downto 0); + signal scBaud : integer; + + + signal tData : DATA; + + -- + -- UART + -- + signal scUARTsend, scUartReadEnable : std_logic; + signal scUARTSempty, scUARTSfull : std_logic; + signal scUARTSalmostE, scUARTSalmostF : std_logic; + signal scUARTRempty, scUARTRfull : std_logic; + signal scUARTRalmostE, scUARTRalmostF : std_logic; + + + -- + -- FSM + -- + type states is (st_start, st_idle, st_read, st_write); + signal current_state : states; + +begin + + scBaud <= to_integer(unsigned(srBaud)); + + odDebug <= srTransmit(7 downto 0); + + uart0: UART + generic map( + GEN_SysClockinHz => GEN_SysClockinHz, + GEN_Baudrate => GEN_Baudrate, + GEN_HasExternBaudLimit => GEN_HasExternBaudLimit + ) + port map( + iSysClk => iClk, + ieClkEn => '1', + iReset => iReset, + icBaudLExt => scBaud, + icSend => scUARTsend, + idDataSend => srTransmit(7 downto 0), + ocSEmpty => scUARTSempty, + ocSFull => scUARTSfull, + ocSAlmostE => scUARTSalmostE, + ocSAlmostF => scUARTSalmostF, + odTransmit => odRS232, + odDataRcvd => srReceive(7 downto 0), + ocREmpty => scUARTRempty, + ocRFull => scUARTRfull, + ocRAlmostE => scUARTRalmostE, + ocRAlmostF => scUARTRalmostF, + icRReadEn => scUartReadEnable, + idReceive => idRS232 + ); + + srStatus <= scUARTRempty & scUARTRfull & scUARTRalmostE & scUARTRalmostF & scUARTSempty & scUARTSfull & scUARTSalmostE & scUARTSalmostF & x"000000"; + + ocInterrupt <= not scUARTRempty; + + process(iClk, iReset) + begin + if (iReset = '1') then + srBaud <= (others=>'0'); + srTransmit <= x"00000000"; + srReceive(30 downto 8) <= (others=>'0'); + + current_state <= st_start; + + elsif (rising_edge(iClk)) then + case current_state is + when st_start => + scUARTsend <= '0'; + scUartReadEnable <= '0'; + + current_state <= st_idle; + when st_idle => + if (icEnable = '1' and idAddress >= GEN_start and idAddress <= GEN_start + 2) then + + -- Status Register + if (idAddress = GEN_start) then + if (icRnotW = '0') then + + scUARTsend <= '0'; + scUartReadEnable <= '0'; + + + current_state <= st_write; + + else + tData <= srStatus; + + scUARTsend <= '0'; + scUartReadEnable <= '0'; + + + current_state <= st_read; + end if; + -- Transmit Register + elsif(idAddress = GEN_start+1) then + if (icRnotW = '0') then + srTransmit <= bdData; + + scUARTsend <= '1'; + scUartReadEnable <= '0'; + + + current_state <= st_write; + + else + tData <= (others=>'0'); + + scUARTsend <= '0'; + scUartReadEnable <= '0'; + + + current_state <= st_read; + end if; + + -- receive Register + elsif(idAddress = GEN_start+2) then + if (icRnotW = '0') then + + scUARTsend <= '0'; + scUartReadEnable <= '0'; + + + current_state <= st_write; + + else + tData <= srReceive; + + scUARTsend <= '0'; + scUartReadEnable <= '1'; + + + current_state <= st_read; + end if; + end if; + + else + scUARTsend <= '0'; + scUartReadEnable <= '0'; + + current_state <= st_idle; + end if; + when st_read => + scUARTsend <= '0'; + scUartReadEnable <= '0'; + + current_state <= st_idle; + + when st_write => + scUARTsend <= '0'; + scUartReadEnable <= '0'; + + current_state <= st_idle; + end case; + end if; + end process; + + + bdData <= srStatus when icRnotW = '1' and idAddress=GEN_start else + srReceive when icRnotW = '1' and idAddress=GEN_start+2 else + (others => 'Z'); + +end arch; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/MemGuard.vhd b/src/MemGuard.vhd new file mode 100644 index 0000000..a2bff69 --- /dev/null +++ b/src/MemGuard.vhd @@ -0,0 +1,46 @@ +------------------------------------------------------- +--! @file +--! @brief memory guard to only answer for the correct memory space +--! @author Dominik Meyer +--! @email dmeyer@hsu-hh.de +--! @date 2013-07-18 +------------------------------------------------------- + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + + +--! memory guard to only answer for the correct memory space + +entity MemGuard is + generic ( + GEN_start : std_logic_vector(15 downto 0) := x"0000"; + GEN_end : std_logic_vector(15 downto 0) := x"0004" + + ); + + port ( + icAddr : in std_logic_vector(15 downto 0); + ocEnable : out std_logic + + ); +end MemGuard; + +architecture arch of MemGuard is + +begin + + + process(icAddr) + begin + if (icAddr >= GEN_start and icAddr <= GEN_end) then + ocEnable <= '1'; + else + ocEnable <= '0'; + end if; + end process; + +end arch; + diff --git a/src/MemoryMapper.vhd b/src/MemoryMapper.vhd new file mode 100644 index 0000000..20e98bc --- /dev/null +++ b/src/MemoryMapper.vhd @@ -0,0 +1,54 @@ +------------------------------------------------------- +--! @file +--! @brief Maps memory devices to a given memory space +--! @author Dominik Meyer +--! @email dmeyer@hsu-hh.de +--! @date 2010-06-03 +------------------------------------------------------- + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + + +--! Maps memory devices to a given memory space +entity MemoryMapper is + port( + start : in std_logic_vector(15 downto 0); --! start of memory space + stop : in std_logic_vector(15 downto 0); --! end of mempry space + + adr_in : in std_logic_vector(15 downto 0); + + req_in : in std_logic; --! ram request type + req_out : out std_logic; --! ram request type + + enable : out std_logic; + + adr_out : out std_logic_vector(15 downto 0) + + ); +end MemoryMapper; + + +--! architecture to map memory devices to memory space +architecture arch of MemoryMapper is + +begin + + process(adr_in, req_in, start, stop) + begin + + if (adr_in >= start and adr_in <= stop) then + req_out <= req_in; + adr_out <= adr_in-start; + enable <= '1'; + else + req_out <= '0'; + enable <= '0'; + adr_out <= (others => 'Z'); + end if; + end process; + +end arch; + diff --git a/src/RAM.vhd b/src/RAM.vhd index d36ab4c..c97cea5 100644 --- a/src/RAM.vhd +++ b/src/RAM.vhd @@ -34,17 +34,61 @@ architecture arch of RAM is type MEMORY is ARRAY(0 to 255) of DATA; --! array of data words constant Prog1 : MEMORY := ( --! 4k * 32bit of RAM - 1 => B"00111100001000000000000000000101", --lui $1, 5 - 2 => B"00111100010000000000000000000110", --lui $2, 6 - 3 => B"00111100011000000000000000000000", --lui $3, 0 - 4 => B"00111100100000000000000000000001", --lui $4, 1 - 5 => B"00010000101000000001000000000000", --add $5, $0, $2 - 6 => B"00010000011000110000100000000000", --add $3, $3, $1 - 7 => B"00010100101001010010000000000000", --sub $5, $5, $4 - 8 => B"00110000000000000000000000001010", --jpz end - 9 => B"00111000000000000000000000000110", --jmp loop - 10 => B"11111100000000000000000000000000", --hlt - + 0 => B"00001100001000001111111111110000", --loa $1, 65520 + 1 => B"01000011111000000000000000000100", --jmc print + 2 => B"01000011111000000000000000100010", --jmc wait + 3 => B"00111000000000000000000000000000", --jmp start + 4 => B"00010010100000010000000000000000", --add $20, $1, $0 + 5 => B"00001000000101001111111111110001", --sto $20, 65521 + 6 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 7 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 8 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 9 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 10 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 11 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 12 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 13 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 14 => B"00001000000101001111111111110001", --sto $20, 65521 + 15 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 16 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 17 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 18 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 19 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 20 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 21 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 22 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 23 => B"00001000000101001111111111110001", --sto $20, 65521 + 24 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 25 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 26 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 27 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 28 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 29 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 30 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 31 => B"00000110100101000000000000000000", --shr $20, $20, $0 + 32 => B"00001000000101001111111111110001", --sto $20, 65521 + 33 => B"01000100000111110000000000000000", --ret + 34 => B"00111101010000000000001001011000", --lui $10, 600 + 35 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 36 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 37 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 38 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 39 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 40 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 41 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 42 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 43 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 44 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 45 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 46 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 47 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 48 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 49 => B"00000001010010100000000000000000", --shl $10, $10, $0 + 50 => B"00111101011000000000000000000001", --lui $11, 1 + 51 => B"00010101010010100101100000000000", --sub $10, $10, $11 + 52 => B"00110000000000000000000000110110", --jpz endloop + 53 => B"00111000000000000000000000110011", --jmp loop + 54 => B"01000100000111110000000000000000", --ret others => (others => '0') @@ -67,17 +111,19 @@ begin tData <= (others => '0'); elsif (rising_edge(iClk)) then - if (icRnotW = '0' and icEnable = '1') then - sRam(conv_integer(unsigned(idAddress))) <= bdData; - else - tData <= sRam(conv_integer(unsigned(idAddress))); - end if; + if (icEnable = '1') then + if (icRnotW = '0') then + sRam(conv_integer(unsigned(idAddress))) <= bdData; + else + tData <= sRam(conv_integer(unsigned(idAddress))); + end if; + end if; end if; end process; - bdData <= tData when icRnotW = '1' else + bdData <= tData when icRnotW = '1' and icEnable='1' else (others => 'Z'); end arch; diff --git a/src/Rechner.vhd b/src/Rechner.vhd deleted file mode 100644 index 8c2c0cb..0000000 --- a/src/Rechner.vhd +++ /dev/null @@ -1,68 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; - -library work; -use work.cpupkg.all; - -entity Rechner is -- Rechner setzt sich aus CPU, RAM und Bus zusammen -port( clk : in std_logic; -- Taktsignal - reset : in std_logic; -- Resetsignal - data_print_1: out DATA; - data_print_2: out DATA - ); -end Rechner; - -architecture Struktur of Rechner is - - signal DATAbus : std_logic_vector(31 downto 0); -- DATAbus - signal address : std_logic_vector(15 downto 0); -- Adressbus - signal rw_ram : std_logic; -- read/write-Signal RAM - signal enable : std_logic; - - component CPU is - Port( - iClk : in std_logic; - iReset : in std_logic; - bdData : inout DATA; --! connection to databus - odAddress : out std_logic_vector(15 downto 0); --! connection to addressbus - ocEnable : out std_logic; --! enable or disable RAM - ocRnotW : out std_logic --! read/write control - ); - end component; - - component RAM is - port ( - iClk : in std_logic; - iReset : in std_logic; - bdData : inout DATA; --! connection to databus - idAddress : in std_logic_vector(15 downto 0); --! connection to addressbus - icEnable : in std_logic; --! enable or disable RAM - icRnotW : in std_logic --! read/write control - - ); - end component; - - -begin - - - CPU_1: CPU port map( - iClk => clk, - iReset => reset, - bdData => DATAbus, - odAddress => address, - ocEnable => enable, - ocRnotW => rw_ram); - - RAM_1: RAM port map( - iClk => clk, - iReset => reset, - bdData => DATAbus, - idAddress => address, - icEnable => enable, - icRnotW => rw_ram); - - data_print_1 <= DATAbus; -- Ausgabe des DATAbus auf dem LCD-Display - data_print_2 <= "0000000000000000" & address; - -end Struktur; diff --git a/src/RegFile.vhd b/src/RegFile.vhd index e92d177..d585481 100644 --- a/src/RegFile.vhd +++ b/src/RegFile.vhd @@ -35,6 +35,8 @@ entity RegFile is odRegA : out DATA; odRegB : out DATA; + icPC : in std_logic; -- select PC as input to RegisterFile + idPC : in DATA; icRegINsel : in std_logic_vector(4 downto 0); @@ -76,7 +78,11 @@ begin elsif (rising_edge(iClk)) then if (icLoadEn = '1') then - registerFile(to_integer(unsigned(icRegINsel))) <= idDataIn; + if (icPC = '0') then + registerFile(to_integer(unsigned(icRegINsel))) <= idDataIn; + else + registerFile(to_integer(unsigned(icRegINsel))) <= idPC; + end if; sdCarry <= idCarryIn; sdZero <= idZeroIn; diff --git a/src/SOC.ucf b/src/SOC.ucf deleted file mode 100644 index 4b38205..0000000 --- a/src/SOC.ucf +++ /dev/null @@ -1,18 +0,0 @@ -NET clk LOC = C9; # Taktsignal Taktgenerator -NET clk_man LOC = H18; # Manuelles Taktsignal �ber Taster button north - -NET reset LOC = N17; # Reset, Schiebeschalter links - -NET switch(0) LOC = L13; # SW0 -NET switch(1) LOC = L14; # SW1 - -NET led(0) LOC = F12; -NET led(1) LOC = E12; -NET led(2) LOC = E11; -NET led(3) LOC = F11; -NET led(4) LOC = C11; -NET led(5) LOC = D11; -NET led(6) LOC = E9; -NET led(7) LOC = F9; - -NET "clk_man" CLOCK_DEDICATED_ROUTE = FALSE; \ No newline at end of file diff --git a/src/SOC.vhd b/src/SOC.vhd index f994464..1ce7a00 100644 --- a/src/SOC.vhd +++ b/src/SOC.vhd @@ -1,68 +1,197 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.STD_LOGIC_ARITH.ALL; - +library ieee; +use ieee.std_logic_1164.all; + library work; -use work.cpupkg.all; - -entity SOC is -- Testumgebung f�r Rechner -port(clk : in std_logic; -- Taktsignal - clk_man : in std_logic; -- manuelles Taktsignal - reset : in std_logic; -- Resetsignal - led : out std_logic_vector(7 downto 0); - switch : in std_logic_vector(1 downto 0)); - -end SOC; - -architecture Struktur of SOC is - -component Rechner is -- Rechner setzt sich aus CPU, RAM und Bus zusammen -port( clk : in std_logic; -- Taktsignal - reset : in std_logic; -- Resetsignal +use work.cpupkg.all; + +entity SOC is -- Rechner setzt sich aus CPU, RAM und Bus zusammen +port( clk : in std_logic; -- Taktsignal + reset : in std_logic; -- Resetsignal + odRS232 : out std_logic; + idRS232 : in std_logic; data_print_1: out DATA; - data_print_2: out DATA); -- Ausgabe -end component Rechner; - -component antibeat_device is - port ( - button_in : in std_logic; --! the button input, for example the button from an fpga - button_out : out std_logic; --! the button output, for example going to the reset or clk of a processor - counter : in std_logic_vector(31 downto 0); --! the number of clk ticks to wait - clk : in std_logic; --! input clock - reset : in std_logic - ); -end component antibeat_device; - - -signal data_print_1 : std_logic_vector(31 downto 0); -signal data_print_2 : std_logic_vector(31 downto 0); -signal sig_entprellt : std_logic; - -signal output : std_logic_vector(15 downto 0); -signal clk_out : std_logic; -begin - - -- select what to display on led - led <= --(others => '1') when reset='1' else - output(15 downto 8) when switch(0)='1' else - output(7 downto 0); - - output <= data_print_1(15 downto 0) when switch(1) = '0' else - data_print_2(15 downto 0); - - antibeat: antibeat_device - port map( - button_in => clk_man, - button_out => clk_out, - counter => x"019BFCC0", - clk => clk, - reset => reset - ); - - - Rechner_0 : Rechner port map(clk => clk_out, - reset => reset, - data_print_1=> data_print_1, - data_print_2=> data_print_2); - -end Struktur; + data_print_2: out DATA; + ic200MhzClk : in std_logic + ); +end SOC; + +architecture arch of SOC is + + component CPU is + Port( + iClk : in std_logic; + iReset : in std_logic; + bdData : inout DATA; --! connection to databus + odAddress : out std_logic_vector(15 downto 0); --! connection to addressbus + ocEnable : out std_logic; --! enable or disable RAM + ocRnotW : out std_logic --! read/write control + ); + end component; + + component RAM is + port ( + iClk : in std_logic; + iReset : in std_logic; + bdData : inout DATA; --! connection to databus + idAddress : in std_logic_vector(15 downto 0); --! connection to addressbus + icEnable : in std_logic; --! enable or disable RAM + icRnotW : in std_logic --! read/write control + + ); + end component; + + + component MemoryMapper + port ( + start : in std_logic_vector ( 15 downto 0 ); + stop : in std_logic_vector ( 15 downto 0 ); + adr_in : in std_logic_vector ( 15 downto 0 ); + req_in : in std_logic; + req_out : out std_logic; + enable : out std_logic; + adr_out : out std_logic_vector ( 15 downto 0 ) + ); + end component; + + + component MMIO_Uart + generic ( + GEN_start : std_logic_vector ( 15 downto 0 ); + GEN_SysClockinHz : integer; + GEN_Baudrate : integer; + GEN_HasExternBaudLimit : boolean + ); + port ( + odRS232 : out std_logic; + idRS232 : in std_logic; + ocInterrupt : out std_logic; --! high if data is available + odDebug : out std_logic_vector(7 downto 0); + iClk : in std_logic; + iReset : in std_logic; + bdData : inout DATA; + idAddress : in ADDRESS; + icEnable : in std_logic; + icRnotW : in std_logic + ); + end component; + + component clkDivider + generic ( + GEN_FreqIn_Hz : integer; + GEN_FreqOut_Hz : integer + ); + port ( + iClk_in : in STD_LOGIC; + iReset : in STD_LOGIC; + oClk_out : out STD_LOGIC + ); + end component; + + + signal DATAbus : std_logic_vector(31 downto 0); -- DATAbus + signal address : std_logic_vector(15 downto 0); -- Adressbus + signal rw_ram : std_logic; -- read/write-Signal RAM + signal enable : std_logic; + + signal scRAMenable : std_logic; + signal scRAM_RnotW : std_logic; + signal scRAM_address : std_logic_vector(15 downto 0); + + signal scUARTenable : std_logic; + signal scUART_RnotW : std_logic; + signal scUART_address : std_logic_vector(15 downto 0); + + signal scClk20Mhz : std_logic; + + signal sdDebug : std_logic_vector(7 downto 0); + + signal scReset : std_logic; + +begin + + scReset <= not reset; + + divider0:clkDivider + generic map( + GEN_FreqIn_Hz => 200000000, + GEN_FreqOut_Hz => 20000000 + ) + port map( + iClk_in => ic200MhzClk, + iReset => '0', + oClk_out => scClk20Mhz + ); + + + + + CPU_1: CPU port map( + iClk => scClk20Mhz, + iReset => scReset, + bdData => DATAbus, + odAddress => address, + ocEnable => enable, + ocRnotW => rw_ram); + + + + mapperRAM: MemoryMapper + port map( + start => x"0000", + stop => x"00FF", + adr_in => address, + req_in => rw_ram, + req_out => scRAM_RnotW, + enable => scRAMenable, + adr_out => scRAM_address + ); + + + + RAM_1: RAM port map( + iClk => scClk20Mhz, + iReset => scReset, + bdData => DATAbus, + idAddress => scRAM_address, + icEnable => scRAMenable, + icRnotW => scRAM_RnotW); + + + + mapperUart: MemoryMapper + port map( + start => x"FFF0", + stop => x"FFF2", + adr_in => address, + req_in => rw_ram, + req_out => scUART_RnotW, + enable => scUARTenable, + adr_out => scUART_address + ); + + + uart0: MMIO_Uart + generic map( + GEN_start => x"0000", + GEN_SysClockinHz => 20000000, + GEN_Baudrate => 57600, + GEN_HasExternBaudLimit => false + ) + port map( + odRS232 => odRS232, + idRS232 => idRS232, + ocInterrupt => open, + odDebug => sdDebug, + iClk => scClk20Mhz, + iReset => scReset, + bdData => DATAbus, + idAddress => scUART_address, + icEnable => scUARTenable, + icRnotW => scUART_RnotW + ); + + + data_print_1 <= DATAbus; + data_print_2 <= x"000000" & sdDebug; + +end arch; diff --git a/src/Steuerwerk.vhd b/src/Steuerwerk.vhd index c94af05..6652d08 100644 --- a/src/Steuerwerk.vhd +++ b/src/Steuerwerk.vhd @@ -27,14 +27,17 @@ entity Steuerwerk is ocLoadInstr : out std_logic; --! load instruction control signal ocNextPC : out std_logic; --! increment pc ocAddrSel : out std_logic; --! pc on addressbus - ocJump : out std_logic --! do a ocJump + ocJump : out std_logic; --! do a ocJump + ocPCregister : out std_logic; --! put PC to register File + ocUsePC : out std_logic; --! use Register to fill in the PC + ocLoad : out std_logic --! put databus to ALU immediate port ); end Steuerwerk; architecture arch of Steuerwerk is type STATES is (load, decode, exshl, exshr, exsto, exloa, exli, exadd, exsub, exaddc, exsubc, - exopor, exopand, exopxor, exopnot, exjpz, exjpc, exjmp, exhlt); + exopor, exopand, exopxor, exopnot, exjpz, exjpc, exjmp, exhlt, exjmc, exret); signal sState, sState_next : STATES; @@ -84,7 +87,8 @@ begin sState_next <= load; end if; when jmp => sState_next <= exjmp; - + when jmc => sState_next <= exjmc; + when ret => sState_next <= exret; when hlt => sState_next <= exhlt; end case; when exhlt => sState_next <= exhlt; @@ -109,6 +113,9 @@ begin ocNextPC <= '0'; -- do not increment pc ocAddrSel <= '1'; -- pc on addressbus ocJump <= '0'; -- no ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; when decode => ocRnotWRam <= '1'; -- read from RAM @@ -118,6 +125,9 @@ begin ocNextPC <= '1'; -- do not increment pc ocAddrSel <= '0'; -- pc on addressbus ocJump <= '0'; -- no ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; when exshl => ocRnotWRam <= '0'; -- read from RAM @@ -127,6 +137,9 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '0'; -- no ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; when exshr => ocRnotWRam <= '0'; -- read from RAM @@ -136,7 +149,10 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '0'; -- no ocJump - + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; + when exsto => ocRnotWRam <= '0'; -- write to RAM ocLoadEn <= '0'; -- do not save result @@ -144,8 +160,11 @@ begin ocLoadInstr <= '0'; -- do not load instruction ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus - ocJump <= '0'; -- no ocJump - + ocJump <= '0'; -- no ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; + when exloa => ocRnotWRam <= '1'; -- read from RAM ocLoadEn <= '1'; -- save result @@ -154,7 +173,10 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '0'; -- no ocJump - + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '1'; + when exli => ocRnotWRam <= '0'; -- read from RAM ocLoadEn <= '1'; -- save result @@ -163,6 +185,9 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '0'; -- no ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; when exadd => ocRnotWRam <= '0'; -- read from RAM @@ -172,6 +197,9 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '0'; -- no ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; when exsub => ocRnotWRam <= '0'; -- read from RAM @@ -181,6 +209,9 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '0'; -- no ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; when exaddc => ocRnotWRam <= '0'; -- read from RAM @@ -190,6 +221,9 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '0'; -- no ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; when exsubc => ocRnotWRam <= '0'; -- read from RAM @@ -199,6 +233,9 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '0'; -- no ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; when exopor => ocRnotWRam <= '0'; -- read from RAM @@ -208,7 +245,10 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '0'; -- no ocJump - + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; + when exopand => ocRnotWRam <= '0'; -- read from RAM ocLoadEn <= '1'; -- save result @@ -217,7 +257,10 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '0'; -- no ocJump - + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; + when exopxor => ocRnotWRam <= '0'; -- read from RAM ocLoadEn <= '1'; -- save result @@ -226,6 +269,9 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '0'; -- no ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; when exopnot => ocRnotWRam <= '0'; -- read from RAM @@ -235,6 +281,9 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '0'; -- no ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; when exjpz => ocRnotWRam <= '0'; -- read from RAM @@ -244,6 +293,9 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '1'; -- ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; when exjpc => ocRnotWRam <= '0'; -- read from RAM @@ -253,7 +305,10 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '1'; -- ocJump - + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; + when exjmp => ocRnotWRam <= '0'; -- read from RAM ocLoadEn <= '0'; -- save result @@ -262,6 +317,34 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '1'; -- ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; + + when exjmc => + ocRnotWRam <= '0'; -- read from RAM + ocLoadEn <= '1'; -- save result + ocEnableRAM <= '0'; -- do not put akku on databus + ocLoadInstr <= '0'; -- do not load instruction + ocNextPC <= '0'; -- increment pc + ocAddrSel <= '0'; -- no pc on addressbus + ocJump <= '1'; -- ocJump + ocPCregister<= '1'; -- put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; + + when exret => + ocRnotWRam <= '0'; -- read from RAM + ocLoadEn <= '0'; -- save result + ocEnableRAM <= '0'; -- do not put akku on databus + ocLoadInstr <= '0'; -- do not load instruction + ocNextPC <= '0'; -- increment pc + ocAddrSel <= '0'; -- no pc on addressbus + ocJump <= '0'; -- ocJump + ocPCregister<= '0'; -- put PC to register File + ocUsePC <= '1'; + ocLoad <= '0'; + when exhlt => ocRnotWRam <= '0'; -- read from RAM ocLoadEn <= '0'; -- save result @@ -270,7 +353,10 @@ begin ocNextPC <= '0'; -- increment pc ocAddrSel <= '0'; -- no pc on addressbus ocJump <= '0'; -- no ocJump - + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; + when others => ocRnotWRam <= '-'; -- read from RAM ocLoadEn <= '-'; -- save result @@ -279,6 +365,10 @@ begin ocNextPC <= '-'; -- increment pc ocAddrSel <= '-'; -- no pc on addressbus ocJump <= '-'; -- no ocJump + ocPCregister <= '0'; -- do not put PC to register File + ocUsePC <= '0'; + ocLoad <= '0'; + end case; end process; diff --git a/src/TBRechner.vhd b/src/TBRechner.vhd index ce7158b..eb8e516 100644 --- a/src/TBRechner.vhd +++ b/src/TBRechner.vhd @@ -39,10 +39,13 @@ ARCHITECTURE behavior OF TBRechner IS -- Component Declaration for the Unit Under Test (UUT) - COMPONENT Rechner + COMPONENT SOC PORT( clk : IN std_logic; reset : IN std_logic; + odRS232 : out std_logic; + idRS232 : in std_logic; + ic200MhzClk : in std_logic; data_print_1 : OUT std_logic_vector(31 downto 0); data_print_2 : OUT std_logic_vector(31 downto 0) ); @@ -51,19 +54,24 @@ ARCHITECTURE behavior OF TBRechner IS --Inputs signal clk : std_logic := '0'; - signal reset : std_logic := '1'; + signal reset : std_logic := '0'; signal data_print_1 : std_logic_vector(31 downto 0); signal data_print_2 : std_logic_vector(31 downto 0); - - -- Clock period definitions + + signal idRS232, odRS232 : std_logic; + + -- Clock period definitions constant clk_period : time := 10 ns; BEGIN -- Instantiate the Unit Under Test (UUT) - uut: Rechner PORT MAP ( + uut: SOC PORT MAP ( clk => clk, + ic200MhzClk => clk, reset => reset, + idRS232 => idRS232, + odRS232 => odRS232, data_print_1 => data_print_1, data_print_2 => data_print_2 ); @@ -84,7 +92,7 @@ BEGIN -- hold reset state for 100 ns. wait for 100 ns; - reset <= '0'; + reset <= '1'; wait for clk_period*10; diff --git a/src/Test.vhd b/src/Test.vhd new file mode 100644 index 0000000..ff15513 --- /dev/null +++ b/src/Test.vhd @@ -0,0 +1,88 @@ +-------------------------------------------------------------------------------- +-- Entity: Test +-- Date:2013-07-18 +-- Author: byterazor +-- +-- Description ${cursor} +-------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity Test is + port ( + idRS232 : in std_logic; + odRS232 : out std_logic; + icReset : in std_logic; + icClk : in std_logic -- input clock, xx MHz. + ); +end Test; + +architecture arch of Test is + + component UART + generic ( + GEN_SysClockinHz : integer; + GEN_Baudrate : integer; + GEN_HasExternBaudLimit : boolean + ); + port ( + iSysClk : in std_logic; + ieClkEn : in std_logic; + iReset : in std_logic; + icBaudLExt : in integer; + icSend : in std_logic; + idDataSend : in std_logic_vector ( 7 downto 0 ); + ocSEmpty : out std_logic; + ocSFull : out std_logic; + ocSAlmostE : out std_logic; + ocSAlmostF : out std_logic; + odTransmit : out std_logic; + odDataRcvd : out std_logic_vector ( 7 downto 0 ); + ocREmpty : out std_logic; + ocRFull : out std_logic; + ocRAlmostE : out std_logic; + ocRAlmostF : out std_logic; + icRReadEn : in std_logic; + idReceive : in std_logic + ); + end component; + + +begin + + uart0: UART + generic map( + GEN_SysClockinHz => 100000000, + GEN_Baudrate => GEN_Baudrate, + GEN_HasExternBaudLimit => GEN_HasExternBaudLimit + ) + port map( + iSysClk => iSysClk, + ieClkEn => ieClkEn, + iReset => iReset, + icBaudLExt => icBaudLExt, + icSend => icSend, + idDataSend => idDataSend, + ocSEmpty => ocSEmpty, + ocSFull => ocSFull, + ocSAlmostE => ocSAlmostE, + ocSAlmostF => ocSAlmostF, + odTransmit => odTransmit, + odDataRcvd => odDataRcvd, + ocREmpty => ocREmpty, + ocRFull => ocRFull, + ocRAlmostE => ocRAlmostE, + ocRAlmostF => ocRAlmostF, + icRReadEn => icRReadEn, + idReceive => idReceive + ); + + +end arch; + diff --git a/src/UART/Fifo.vhd b/src/UART/Fifo.vhd index 411e551..8e0aa19 100644 --- a/src/UART/Fifo.vhd +++ b/src/UART/Fifo.vhd @@ -30,8 +30,8 @@ entity Fifo is iClkRead : in std_logic; icReadEn : in std_logic; - idDataIn : in std_logic_vector(8 downto 0); - odDataOut : out std_logic_vector(8 downto 0); + idDataIn : in std_logic_vector(7 downto 0); + odDataOut : out std_logic_vector(7 downto 0); ocEmpty : out std_logic; ocFull : out std_logic; @@ -44,8 +44,6 @@ end Fifo; architecture arch of Fifo is signal sdDataOut : std_logic_vector(31 downto 0); signal sdDataIn : std_logic_vector(31 downto 0); - signal sdParityIN: std_logic_vector(3 downto 0); - signal sdParityOut:std_logic_vector(3 downto 0); begin FIFO36_inst : FIFO36 @@ -64,7 +62,7 @@ begin ALMOSTEMPTY => ocAlmostE, -- 1-bit almost empty output flag ALMOSTFULL => ocAlmostF, -- 1-bit almost full output flag DO => sdDataOut, -- 32-bit data output - DOP => sdParityOut, -- 4-bit parity data output + DOP => open, -- 4-bit parity data output EMPTY => ocEmpty, -- 1-bit empty output flag FULL => ocFull, -- 1-bit full output flag RDCOUNT => open, -- 13-bit read count output @@ -72,7 +70,7 @@ begin WRCOUNT => open, -- 13-bit write count output WRERR => open, -- 1-bit write error DI => sdDataIn, -- 32-bit data input - DIP => sdParityIn, -- 4-bit parity input + DIP => "1111", -- 4-bit parity input RDCLK => iClkRead, -- 1-bit read clock input RDEN => icReadEn, -- 1-bit read enable input RST => iReset, -- 1-bit reset input @@ -80,9 +78,7 @@ begin WREN => icWriteEn -- 1-bit write enable input ); - odDataOut(8 downto 1) <= sdDataOut(7 downto 0); - odDataOut(0) <= sdParityOut(0); - sdDataIn <= X"000000" & idDataIn(8 downto 1); - sdParityIN <= "000" & idDataIn(0); + odDataOut <= sdDataOut(7 downto 0); + sdDataIn <= X"000000" & idDataIn; end arch; diff --git a/src/UART/Receiver.vhd b/src/UART/Receiver.vhd index f8091d6..d349d85 100644 --- a/src/UART/Receiver.vhd +++ b/src/UART/Receiver.vhd @@ -27,17 +27,15 @@ entity Receiver is ie4BaudClkEn : in std_logic;reset : in std_logic; --! signal description asynchronous reset Rx : in STD_LOGIC; --! signal description signal for the RS232 Rx line data : out STD_LOGIC_VECTOR (7 downto 0); --! signal description last data received - parity : out std_logic; --! signal description - icEnableParity: in std_logic; --! signal description Enable reception of the parity bit ready : out STD_LOGIC); --! '0' signals receving in progress, if '1' after a previous '0' signals data available at end Receiver; architecture Behavioral of Receiver is signal z, tz : integer range 0 to 63; signal result, tresult : STD_LOGIC_VECTOR(7 downto 0); - signal sdParity : std_logic; + begin - process (z, Rx, icEnableParity) + process (z, Rx) begin if z = 0 then if (Rx ='0') then @@ -48,8 +46,7 @@ begin elsif z <= 36 then tz <= z + 1; - elsif (z <= 40 and icEnableParity='1') then - tz <= z+1; + else tz <= 0; @@ -58,12 +55,11 @@ begin tresult <= Rx & result(7 downto 1); - process (iSysClk) + process (reset, iSysClk) begin if (iSysClk'event and iSysClk = '1') then if reset = '1' then z <= 0; - sdParity <= '0'; elsif ie4BaudClkEn = '1' then z <= tz; case z is @@ -91,14 +87,7 @@ begin when 33 => result <= tresult; -- D(7) - - when 37 => - result <= result; - if (icEnableParity='1') then - sdParity <= Rx; - else - sdParity <= '0'; - end if; + -- optional TODO: add check for STOP-Bit(s) when others => result <= result; @@ -106,8 +95,7 @@ begin end if; end if; end process; - - parity <= sdParity; + data <= result; ready <= '1' when z = 0 else '0'; diff --git a/src/UART/ReceiverAndFifo.vhd b/src/UART/ReceiverAndFifo.vhd index 2414665..bfc14a4 100644 --- a/src/UART/ReceiverAndFifo.vhd +++ b/src/UART/ReceiverAndFifo.vhd @@ -22,21 +22,20 @@ use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity ReceiverAndFifo is - port ( - iSysClk : in std_logic; --! signal description System side clock - ieClkEn : in std_logic; + iSysClk : in std_logic; --! signal description System side clock + ieClkEn : in std_logic; ie4xBaudClkEn : in std_logic; --! signal description UART clock (4xBAUD Rate frequency!) - iReset : in std_logic; --! signal description asynchronous reset - icEnableParity: in std_logic; --! signal description allow reception of parity bit - odDataRcvd : out std_logic_vector(7 downto 0); --! signal description data from Fifo - odParity : out std_logic; --! possible parity bit - ocREmpty : out std_logic; --! signal description indicates that Fifo is empty - ocRFull : out std_logic; --! signal description indicates that Fifo is full - ocRAlmostE : out std_logic; --! signal description indicates that Fifo is empty to half full - ocRAlmostF : out std_logic; --! signal description indicates that Fifo is half full to full - icRReadEn : in std_logic; --! signal description get next value from Fifo (Fifo is in First Word Fall Through Mode!) - idReceive : in std_logic --! signal description signal for the RS232 Tx line + iReset : in std_logic; --! signal description asynchronous reset + + odDataRcvd : out std_logic_vector(7 downto 0); --! signal description data from Fifo + ocREmpty : out std_logic; --! signal description indicates that Fifo is empty + ocRFull : out std_logic; --! signal description indicates that Fifo is full + ocRAlmostE : out std_logic; --! signal description indicates that Fifo is empty to half full + ocRAlmostF : out std_logic; --! signal description indicates that Fifo is half full to full + icRReadEn : in std_logic; --! signal description get next value from Fifo (Fifo is in First Word Fall Through Mode!) + + idReceive : in std_logic --! signal description signal for the RS232 Tx line ); end ReceiverAndFifo; @@ -44,14 +43,12 @@ architecture arch of ReceiverAndFifo is component Receiver is port ( - iSysClk : in std_logic; - ie4BaudClkEn : in std_logic; - reset : in STD_LOGIC; - Rx : in STD_LOGIC; - data : out STD_LOGIC_VECTOR (7 downto 0); - parity : out std_logic; - icEnableParity: in std_logic; - ready : out STD_LOGIC); + iSysClk : in std_logic; + ie4BaudClkEn : in std_logic; + reset : in STD_LOGIC; + Rx : in STD_LOGIC; + data : out STD_LOGIC_VECTOR (7 downto 0); + ready : out STD_LOGIC); end component; component Fifo is @@ -64,8 +61,8 @@ architecture arch of ReceiverAndFifo is iClkRead : in std_logic; icReadEn : in std_logic; - idDataIn : in std_logic_vector(8 downto 0); - odDataOut : out std_logic_vector(8 downto 0); + idDataIn : in std_logic_vector(7 downto 0); + odDataOut : out std_logic_vector(7 downto 0); ocEmpty : out std_logic; ocFull : out std_logic; @@ -78,8 +75,7 @@ architecture arch of ReceiverAndFifo is signal scRWrite : std_logic; signal scRWriteEn : std_logic; signal seRReadEn : std_logic; - signal sdDataRcvd : STD_LOGIC_VECTOR (8 downto 0); - signal sdParity : std_logic; + signal sdDataRcvd : STD_LOGIC_VECTOR (7 downto 0); signal scRcvrEmpty : std_logic; signal scRcvrFull : std_logic; @@ -105,8 +101,7 @@ begin icReadEn => seRReadEn, idDataIn => sdDataRcvd, - odDataOut(8 downto 1) => odDataRcvd, - odDataOut(0) => odParity, + odDataOut => odDataRcvd, ocEmpty => scRcvrEmpty, ocFull => scRcvrFull, @@ -126,13 +121,10 @@ begin ie4BaudClkEn => ie4xBaudClkEn, reset => iReset, Rx => idReceive, - data => sdDataRcvd(8 downto 1), - parity => sdDataRcvd(0), - icEnableParity => icEnableParity, + data => sdDataRcvd, ready => scReaderReady ); - - + ReceiverCtrl : process (iSysClk) begin if (rising_edge(iSysClk)) then diff --git a/src/UART/Sender.vhd b/src/UART/Sender.vhd index 938179d..958ea02 100644 --- a/src/UART/Sender.vhd +++ b/src/UART/Sender.vhd @@ -27,17 +27,15 @@ entity Sender is iReset : in STD_LOGIC; --! signal description synchronous reset icSend : in STD_LOGIC; --! signal description force a send of idData : in STD_LOGIC_VECTOR (7 downto 0); --! signal description the data to be sent - idParity : in std_logic; --! signal description the parity bit of the data - icEnableParity:in std_logic; --! signal description enable sending of the parity bit odTransmit : out STD_LOGIC; --! signal description signal for the RS232 Tx line ocReady : out STD_LOGIC; --! signal description signals availability of the Sender (no Sending in Progress) ocSyn : out STD_LOGIC); --! signal description signals sending of first Stop Bit end Sender; architecture Behavioral of Sender is - signal temp, tnext :STD_LOGIC_VECTOR(12 downto 0); + signal temp, tnext :STD_LOGIC_VECTOR(11 downto 0); - type StateType is (WAITING, INIT, HIGH, START, DATA0, DATA1, DATA2, DATA3, DATA4, DATA5, DATA6, DATA7, PARITY, STOP1, STOP2); + type StateType is (WAITING, INIT, HIGH, START, DATA0, DATA1, DATA2, DATA3, DATA4, DATA5, DATA6, DATA7, STOP1, STOP2); signal state : StateType; begin process(iSysClk) @@ -55,11 +53,7 @@ begin case state is when WAITING => if (icSend = '1') then - if (icEnableParity = '1') then - temp <= "11" & idParity & idData & "01"; - else - temp <= "111" & idData & "01"; - end if; + temp <= "11" & idData & "01"; state <= INIT; else state <= WAITING; @@ -96,14 +90,7 @@ begin state <= DATA7; when DATA7 => - if (icEnableParity = '1') then - state <= PARITY; - else - state <= STOP1; - end if; - - when PARITY => - state <= STOP1; + state <= STOP1; when STOP1 => state <= STOP2; @@ -117,7 +104,7 @@ begin end if; end process; - tnext <= '1' & temp(12 downto 1); + tnext <= '1' & temp(11 downto 1); ocReady <= '1' when state = WAITING else '0'; diff --git a/src/UART/SenderAndFifo.vhd b/src/UART/SenderAndFifo.vhd index 6ad3d03..e3079a5 100644 --- a/src/UART/SenderAndFifo.vhd +++ b/src/UART/SenderAndFifo.vhd @@ -32,8 +32,6 @@ entity SenderAndFifo is icSend : in std_logic; --! signal description add data to Fifo (Enable Signal) idDataSend : in std_logic_vector(7 downto 0); --! signal description data to be added to the Fifo - idParity : in std_logic; --! signal description the parity bit for the data - icEnableParity: in std_logic; --! signal description enable the sending of the parity bit ocSEmpty : out std_logic; --! signal description indicates that Fifo is empty ocSFull : out std_logic; --! signal description indicates that Fifo is full ocSAlmostE : out std_logic; --! signal description indicates that Fifo is empty to half full @@ -51,8 +49,6 @@ architecture arch of SenderAndFifo is iReset : in STD_LOGIC; icSend : in STD_LOGIC; idData : in STD_LOGIC_VECTOR (7 downto 0); - idParity : in std_logic; - icEnableParity:in std_logic; odTransmit : out STD_LOGIC; ocReady : out STD_LOGIC; ocSyn : out STD_LOGIC); @@ -68,8 +64,8 @@ architecture arch of SenderAndFifo is iClkRead : in std_logic; icReadEn : in std_logic; - idDataIn : in std_logic_vector(8 downto 0); - odDataOut : out std_logic_vector(8 downto 0); + idDataIn : in std_logic_vector(7 downto 0); + odDataOut : out std_logic_vector(7 downto 0); ocEmpty : out std_logic; ocFull : out std_logic; @@ -82,7 +78,7 @@ architecture arch of SenderAndFifo is signal scSenderRead : std_logic; signal scSenderReadEn : std_logic; - signal sdDataToSend : STD_LOGIC_VECTOR (8 downto 0); + signal sdDataToSend : STD_LOGIC_VECTOR (7 downto 0); signal scSenderEmpty : std_logic; signal scSenderFull : std_logic; signal scSenderAEmpty : std_logic; @@ -97,8 +93,6 @@ architecture arch of SenderAndFifo is signal seSend : std_logic; - signal sdFifoDataIn : std_logic_vector(8 downto 0); - begin scSenderReadEn <= scSenderRead and ieBaudClkEn; @@ -114,7 +108,7 @@ begin iClkRead => iSysClk, icReadEn => scSenderReadEn, - idDataIn => sdFifoDataIn, + idDataIn => idDataSend, odDataOut => sdDataToSend, ocEmpty => scSenderEmpty, @@ -123,9 +117,7 @@ begin ocAlmostE => scSenderAEmpty, ocAlmostF => scSenderAFull ); - - sdFifoDataIn <= idDataSend & idParity; - + ocSEmpty <= scSenderEmpty; ocSFull <= scSenderFull; ocSAlmostE <= scSenderAEmpty; @@ -137,9 +129,7 @@ begin ieBaudClkEn => ieBaudClkEn, iReset => iReset, icSend => scSenderSendReq, - idData => sdDataToSend(8 downto 1), - idParity => sdDataToSend(0), - icEnableParity=>icEnableParity, + idData => sdDataToSend, odTransmit => odTransmit, ocReady => scSenderReady, ocSyn => scSyn diff --git a/src/UART/UART.vhd b/src/UART/UART.vhd index 079604a..6979f3a 100644 --- a/src/UART/UART.vhd +++ b/src/UART/UART.vhd @@ -29,10 +29,9 @@ entity UART is iReset : in std_logic; icBaudLExt : in integer := 0; - icEnableParity : in std_logic := '0'; + icSend : in std_logic; idDataSend : in std_logic_vector(7 downto 0); - idParity : in std_logic := '0'; ocSEmpty : out std_logic; ocSFull : out std_logic; ocSAlmostE : out std_logic; @@ -41,7 +40,6 @@ entity UART is odTransmit : out std_logic; odDataRcvd : out std_logic_vector(7 downto 0); - odParity : out std_logic; ocREmpty : out std_logic; ocRFull : out std_logic; ocRAlmostE : out std_logic; @@ -92,10 +90,9 @@ architecture arch of UART is ieClkEn : in std_logic; ieBaudClkEn : in std_logic; iReset : in std_logic; + icSend : in std_logic; idDataSend : in std_logic_vector(7 downto 0); - idParity : in std_logic; - icEnableParity : in std_logic; ocSEmpty : out std_logic; ocSFull : out std_logic; ocSAlmostE : out std_logic; @@ -113,8 +110,6 @@ architecture arch of UART is iReset : in std_logic; odDataRcvd : out std_logic_vector(7 downto 0); - odParity : out std_logic; - icEnableParity:in std_logic; ocREmpty : out std_logic; ocRFull : out std_logic; ocRAlmostE : out std_logic; @@ -194,9 +189,7 @@ end generate; iReset => iReset, icSend => icSend, - icEnableParity=> icEnableParity, idDataSend => idDataSend, - idParity => idParity, ocSEmpty => ocSEmpty, ocSFull => ocSFull, ocSAlmostE => ocSAlmostE, @@ -212,9 +205,7 @@ end generate; ie4xBaudClkEn => se4BaudReceiver, iReset => iReset, - icEnableParity=>icEnableParity, odDataRcvd => odDataRcvd, - odParity => odParity, ocREmpty => ocREmpty, ocRFull => ocRFull, ocRAlmostE => ocRAlmostE, diff --git a/src/clkDivider.vhd b/src/clkDivider.vhd new file mode 100644 index 0000000..a171130 --- /dev/null +++ b/src/clkDivider.vhd @@ -0,0 +1,72 @@ +-------------------------------------------------------------------------------- +-- Entity: clkDivider +-------------------------------------------------------------------------------- +-- Copyright ... 2011 +-- Filename : clkDivider.vhd +-- Creation date : 2011-05-25 +-- Author(s) : marcel +-- Version : 1.00 +-- Description : generates a clock frequency based on +-- input freuency +-- Attention: avoid "strange" samples as 3:2 +-------------------------------------------------------------------------------- +-- File History: +-- Date Version Author Comment +-- unknown 0.10 marcel Creation of File +-- 2011-05-25 1.00 marcel GENERICs added +-------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + + +--! brief +--! generates a clock frequency based on +--! input freuency +--! Generics can also be used to define ratio (like 4 (IN) : 1(Out)) +--! Attention: avoid "strange" ratios (like 3:2) + +--! detailed +--! see brief + +entity clkDivider is + generic( + GEN_FreqIn_Hz : integer := 200000000; --! signal description input clock frequency in Hz for + GEN_FreqOut_Hz : integer := 100000000 --! signal description output clock frequency in Hz for + ); + port ( + iClk_in : in STD_LOGIC; --! signal description input clock + iReset : in STD_LOGIC; --! signal description asynchronous reset (can be tied to '0') + oClk_out : out STD_LOGIC --! signal description output clock + ); +end clkDivider; + +architecture Behavioral of clkDivider is + constant cLimit : integer := GEN_FreqIn_Hz / (2 * GEN_FreqOut_Hz); + signal sCounter : integer := 0; + signal sClk_out : STD_LOGIC := '0'; +begin + + process (iClk_in, iReset) + begin + if (iReset = '1') then + sCounter <= 0; + sClk_out <= '0'; + + elsif (rising_edge(iClk_in)) then + if (sCounter = (cLimit-1)) then + sCounter <= 0; + sClk_out <= not sClk_out; + + else + sCounter <= sCounter + 1; + + end if; + + end if; + + end process; + + oClk_out <= sClk_out; + +end Behavioral; + diff --git a/src/cpupkg.vhd b/src/cpupkg.vhd index 60f7cdb..17c2e00 100644 --- a/src/cpupkg.vhd +++ b/src/cpupkg.vhd @@ -8,7 +8,7 @@ library IEEE; use IEEE.STD_LOGIC_1164.all; package cpupkg is - type OPTYPE is (shl, shr, sto, loa, li, add, sub, addc, subc, opor, opand, opxor, opnot, jpz, jpc, jmp, hlt); + type OPTYPE is (jmc, shl, shr, sto, loa, li, add, sub, addc, subc, opor, opand, opxor, opnot, jpz, jpc, jmp, hlt, ret); subtype DATA is std_logic_vector(31 downto 0); subtype ADDRESS is std_logic_vector(15 downto 0);