URL
https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk
Subversion Repositories open8_urisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 179 to Rev 180
- ↔ Reverse comparison
Rev 179 → Rev 180
/open8_urisc/trunk/VHDL/o8_crc16_ccitt.vhd
0,0 → 1,189
-- Copyright (c)2020 Jeremy Seth Henry |
-- All rights reserved. |
-- |
-- Redistribution and use in source and binary forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- * Redistributions of source code must retain the above copyright |
-- notice, this list of conditions and the following disclaimer. |
-- * Redistributions in binary form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution, |
-- where applicable (as part of a user interface, debugging port, etc.) |
-- |
-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY |
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY |
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
-- |
-- VHDL Units : o8_crc16_ccitt |
-- Description: Implements the 16-bit CCITT CRC on byte-wide data suitable for |
-- : use with the Open8 CPU. Logic equations were taken from |
-- : Intel/Altera app note AN049. |
-- |
-- Notes : Writing to the byte counter will reset all registers, and to |
-- : should be used to clear the CRC accumulator/byte counter |
-- : between frames. |
-- |
-- Register Map: |
-- Offset Bitfield Description Read/Write |
-- 0x0 AAAAAAAA Data Input register (calc on write)(R/W) |
-- 0x1 AAAAAAAA Byte Counter (clear all on write) (R/W) |
-- 0x2 AAAAAAAA B0 of calculated CRC (RO) |
-- 0x3 AAAAAAAA B1 of calculated CRC (RO) |
-- |
-- Revision History |
-- Author Date Change |
------------------ -------- --------------------------------------------------- |
-- Seth Henry 12/19/19 Design Start |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
|
library work; |
use work.open8_pkg.all; |
|
entity o8_crc16_ccitt is |
generic( |
Reset_Level : std_logic := '1'; |
Address : ADDRESS_TYPE |
); |
port( |
Clock : in std_logic; |
Reset : in std_logic; |
-- |
Bus_Address : in ADDRESS_TYPE; |
Wr_Enable : in std_logic; |
Wr_Data : in DATA_TYPE; |
Rd_Enable : in std_logic; |
Rd_Data : out DATA_TYPE |
); |
end entity; |
|
architecture behave of o8_crc16_ccitt is |
|
constant Poly_Init : std_logic_vector(15 downto 0) := x"0000"; |
|
constant User_Addr : std_logic_vector(15 downto 2) |
:= Address(15 downto 2); |
alias Comp_Addr is Bus_Address(15 downto 2); |
alias Reg_Addr is Bus_Address(1 downto 0); |
signal Reg_Sel : std_logic_vector(1 downto 0); |
signal Addr_Match : std_logic; |
signal Wr_En : std_logic; |
signal Wr_Data_q : DATA_TYPE; |
signal Rd_En : std_logic; |
|
signal Next_Byte : DATA_TYPE; |
signal Byte_Count : DATA_TYPE; |
|
signal Calc_En : std_logic; |
signal Buffer_En : std_logic; |
signal Data : DATA_TYPE; |
signal Exr : DATA_TYPE; |
signal Reg : std_logic_vector(15 downto 0); |
signal Comp_Data : std_logic_vector(15 downto 0); |
|
begin |
|
Addr_Match <= '1' when Comp_Addr = User_Addr else '0'; |
|
Exr(0) <= Reg(0) xor Data(0); |
Exr(1) <= Reg(1) xor Data(1); |
Exr(2) <= Reg(2) xor Data(2); |
Exr(3) <= Reg(3) xor Data(3); |
Exr(4) <= Reg(4) xor Data(4); |
Exr(5) <= Reg(5) xor Data(5); |
Exr(6) <= Reg(6) xor Data(6); |
Exr(7) <= Reg(7) xor Data(7); |
|
CRC16_Calc: process( Clock, Reset ) |
begin |
if( Reset = Reset_Level )then |
Reg_Sel <= "00"; |
Rd_En <= '0'; |
Rd_Data <= x"00"; |
Wr_En <= '0'; |
Wr_Data_q <= x"00"; |
|
Byte_Count <= x"00"; |
Calc_En <= '0'; |
Buffer_En <= '0'; |
Data <= x"00"; |
Reg <= x"0000"; |
elsif( rising_edge(Clock) )then |
Rd_Data <= (others => '0'); |
Rd_En <= Addr_Match and Rd_Enable; |
Wr_En <= Addr_Match and Wr_Enable; |
Wr_Data_q <= Wr_Data; |
Reg_Sel <= Reg_Addr; |
|
Calc_En <= '0'; |
Buffer_En <= Calc_En; |
|
if( Calc_En = '1' )then |
Reg(0) <= Reg(8) xor Exr(4) xor Exr(0); |
Reg(1) <= Reg(9) xor Exr(5) xor Exr(1); |
Reg(2) <= Reg(10) xor Exr(6) xor Exr(2); |
Reg(3) <= Reg(11) xor Exr(0) xor Exr(7) xor Exr(3); |
Reg(4) <= Reg(12) xor Exr(1) ; |
Reg(5) <= Reg(13) xor Exr(2) ; |
Reg(6) <= Reg(14) xor Exr(3) ; |
Reg(7) <= Reg(15) xor Exr(4) xor Exr(0); |
Reg(8) <= Exr(0) xor Exr(5) xor Exr(1); |
Reg(9) <= Exr(1) xor Exr(6) xor Exr(2); |
Reg(10) <= Exr(2) xor Exr(7) xor Exr(3); |
Reg(11) <= Exr(3) ; |
Reg(12) <= Exr(4) xor Exr(0); |
Reg(13) <= Exr(5) xor Exr(1); |
Reg(14) <= Exr(6) xor Exr(2); |
Reg(15) <= Exr(7) xor Exr(3); |
end if; |
|
if( Buffer_En = '1' )then |
Byte_Count <= Byte_Count + 1; |
Comp_Data <= Reg xor x"FFFF"; |
end if; |
|
if( Wr_En = '1' )then |
case( Reg_Sel )is |
when "00" => -- Load next byte |
Data <= Wr_Data_q; |
Calc_En <= '1'; |
|
when "01" => -- Clear accumulator and byte counter |
Byte_Count <= x"00"; |
Reg <= Poly_Init; |
|
when others => null; |
end case; |
end if; |
|
if( Rd_En = '1' )then |
case( Reg_Sel )is |
when "00" => -- Read last byte |
Rd_Data <= Data; |
|
when "01" => -- Read the byte counter |
Rd_Data <= Byte_Count; |
|
when "10" => -- Read the lower byte of the calculated CRC |
Rd_Data <= Comp_Data(7 downto 0); |
|
when "11" => -- Read the upper byte of the calculated CRC |
Rd_Data <= Comp_Data(15 downto 8); |
|
when others => null; |
end case; |
end if; |
|
end if; |
end process; |
|
end architecture; |
open8_urisc/trunk/VHDL/o8_crc16_ccitt.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: open8_urisc/trunk/VHDL/o8_datalatch.vhd
===================================================================
--- open8_urisc/trunk/VHDL/o8_datalatch.vhd (nonexistent)
+++ open8_urisc/trunk/VHDL/o8_datalatch.vhd (revision 180)
@@ -0,0 +1,112 @@
+-- Copyright (c)2006, 2016, 2019 Jeremy Seth Henry
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution,
+-- where applicable (as part of a user interface, debugging port, etc.)
+--
+-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
+-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
+-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+-- VHDL Units : o8_datalatch
+-- Description: Latches a byte of external data and issues an interrupt on
+-- capture.
+--
+--
+-- Register Map:
+-- Offset Bitfield Description Read/Write
+-- 0x00 AAAAAAAA Latched Value (RW)
+--
+-- Note: Cut the path between LData_q1 and L_Data for timing analysis
+--
+-- Revision History
+-- Author Date Change
+------------------ -------- ---------------------------------------------------
+-- Seth Henry 01/22/20 Design Start
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+library work;
+ use work.open8_pkg.all;
+
+entity o8_datalatch is
+generic(
+ Reset_Level : std_logic;
+ Address : ADDRESS_TYPE
+);
+port(
+ Clock : in std_logic;
+ Reset : in std_logic;
+ --
+ Bus_Address : in ADDRESS_TYPE;
+ Rd_Enable : in std_logic;
+ Rd_Data : out DATA_TYPE;
+ Interrupt : out std_logic;
+ --
+ L_Strobe : in std_logic;
+ L_Data : in DATA_TYPE
+);
+end entity;
+
+architecture behave of o8_datalatch is
+
+ constant User_Addr : std_logic_vector(15 downto 0) := Address;
+ alias Comp_Addr is Bus_Address(15 downto 0);
+ signal Addr_Match : std_logic;
+ signal Rd_En : std_logic;
+
+ signal Strobe_sr : std_logic_vector(3 downto 0);
+ signal Strobe_re : std_logic;
+
+ signal LData_q1 : DATA_TYPE;
+ signal LData_q2 : DATA_TYPE;
+ signal LData_q3 : DATA_TYPE;
+
+begin
+
+ Addr_Match <= Rd_Enable when Comp_Addr = User_Addr else '0';
+ Strobe_re <= Strobe_sr(2) and not Strobe_sr(3);
+
+ io_reg: process( Clock, Reset )
+ begin
+ if( Reset = Reset_Level )then
+ Rd_En <= '0';
+ Rd_Data <= x"00";
+ Strobe_sr <= (others => '0');
+ Interrupt <= '0';
+ LData_q1 <= x"00";
+ LData_q2 <= x"00";
+ LData_q3 <= x"00";
+ elsif( rising_edge( Clock ) )then
+ Strobe_sr <= Strobe_sr(2 downto 0) & L_Strobe;
+
+ LData_q1 <= L_Data;
+ LData_q2 <= LData_q1;
+ Interrupt <= Strobe_re;
+ if( Strobe_re = '1' )then
+ LData_q3 <= LData_q2;
+ end if;
+
+ Rd_Data <= (others => '0');
+ Rd_En <= Addr_Match;
+ if( Rd_En = '1' )then
+ Rd_Data <= LData_q3;
+ end if;
+ end if;
+ end process;
+
+end architecture;
open8_urisc/trunk/VHDL/o8_datalatch.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: open8_urisc/trunk/VHDL/o8_pit.vhd
===================================================================
--- open8_urisc/trunk/VHDL/o8_pit.vhd (revision 179)
+++ open8_urisc/trunk/VHDL/o8_pit.vhd (revision 180)
@@ -1,4 +1,4 @@
--- Copyright (c)2013 Jeremy Seth Henry
+-- Copyright (c)2006, 2016, 2019 Jeremy Seth Henry
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
@@ -21,7 +21,7 @@
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
--- VHDL Units : o8_pit
+-- VHDL Units : o8_timer
-- Description: Provides an 8-bit microsecond resolution timer for generating
-- : periodic interrupts for the Open8 CPU.
--
@@ -29,6 +29,12 @@
-- : output staying high indefinitely. This may cause an issue if
-- : the output is connected to an interrupt input.
-- : Also provides uSec_Tick as an output
+--
+-- Revision History
+-- Author Date Change
+------------------ -------- ---------------------------------------------------
+-- Seth Henry 07/28/11 Design Start
+-- Seth Henry 12/19/19 Renamed Tmr_Out to Interrupt
library ieee;
use ieee.std_logic_1164.all;
@@ -39,7 +45,7 @@
library work;
use work.open8_pkg.all;
-entity o8_pit is
+entity o8_timer is
generic(
Sys_Freq : real;
Reset_Level : std_logic;
@@ -55,12 +61,11 @@
Wr_Data : in DATA_TYPE;
Rd_Enable : in std_logic;
Rd_Data : out DATA_TYPE;
- --
- Tmr_Out : out std_logic
+ Interrupt : out std_logic
);
end entity;
-architecture behave of o8_pit is
+architecture behave of o8_timer is
constant User_Addr : ADDRESS_TYPE := Address;
alias Comp_Addr is Bus_Address(15 downto 0);
@@ -88,7 +93,7 @@
constant DLY_1USEC_VAL: integer := integer(Sys_Freq / 1000000.0);
constant DLY_1USEC_WDT: integer := ceil_log2(DLY_1USEC_VAL - 1);
constant DLY_1USEC : std_logic_vector :=
- conv_std_logic_vector( DLY_1USEC_VAL - 1, DLY_1USEC_WDT);
+ conv_std_logic_vector(DLY_1USEC_VAL - 1, DLY_1USEC_WDT);
signal uSec_Cntr : std_logic_vector( DLY_1USEC_WDT - 1 downto 0 )
:= (others => '0');
@@ -131,7 +136,7 @@
uSec_Tick_i <= '0';
if( uSec_Cntr = 0 )then
uSec_Cntr <= DLY_1USEC;
- uSec_Tick_i <= or_reduce(Interval);
+ uSec_Tick_i <= '1';
end if;
end if;
end process;
@@ -140,13 +145,13 @@
begin
if( Reset = Reset_Level )then
Timer_Cnt <= x"00";
- Tmr_Out <= '0';
+ Interrupt <= '0';
elsif( rising_edge(Clock) )then
- Tmr_Out <= '0';
+ Interrupt <= '0';
Timer_Cnt <= Timer_Cnt - uSec_Tick_i;
if( or_reduce(Timer_Cnt) = '0' )then
Timer_Cnt <= Interval;
- Tmr_Out <= or_reduce(Interval); -- Only issue output on Int > 0
+ Interrupt <= or_reduce(Interval); -- Only trigger on Int > 0
end if;
end if;
end process;
/open8_urisc/trunk/VHDL/o8_register.vhd
0,0 → 1,116
-- Copyright (c)2006, 2016, 2019 Jeremy Seth Henry |
-- All rights reserved. |
-- |
-- Redistribution and use in source and binary forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- * Redistributions of source code must retain the above copyright |
-- notice, this list of conditions and the following disclaimer. |
-- * Redistributions in binary form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution, |
-- where applicable (as part of a user interface, debugging port, etc.) |
-- |
-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY |
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY |
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
-- |
-- VHDL Units : o8_register |
-- Description: Provides a single addressible 8-bit register |
-- |
-- Register Map: |
-- Offset Bitfield Description Read/Write |
-- 0x00 AAAAAAAA Registered Outputs (RW) |
-- |
-- Revision History |
-- Author Date Change |
------------------ -------- --------------------------------------------------- |
-- Seth Henry 12/20/19 Design Start |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
use ieee.std_logic_misc.all; |
|
library work; |
use work.open8_pkg.all; |
|
entity o8_register is |
generic( |
Default_Value : DATA_TYPE := x"00"; |
Reset_Level : std_logic; |
Address : ADDRESS_TYPE |
); |
port( |
Clock : in std_logic; |
Reset : in std_logic; |
-- |
Bus_Address : in ADDRESS_TYPE; |
Wr_Enable : in std_logic; |
Wr_Data : in DATA_TYPE; |
Rd_Enable : in std_logic; |
Rd_Data : out DATA_TYPE; |
-- |
Register_Out : out DATA_TYPE |
); |
end entity; |
|
architecture behave of o8_register is |
|
function ceil_log2 (x : in natural) return natural is |
variable retval : natural; |
begin |
retval := 1; |
while ((2**retval) - 1) < x loop |
retval := retval + 1; |
end loop; |
return retval; |
end function; |
|
constant User_Addr : std_logic_vector(15 downto 0) |
:= Address(15 downto 0); |
alias Comp_Addr is Bus_Address(15 downto 0); |
signal Addr_Match : std_logic; |
signal Wr_En : std_logic; |
signal Wr_Data_q : DATA_TYPE; |
signal Reg_Out : DATA_TYPE; |
signal Rd_En : std_logic; |
|
begin |
|
Addr_Match <= '1' when Comp_Addr = User_Addr else '0'; |
|
io_reg: process( Clock, Reset ) |
begin |
if( Reset = Reset_Level )then |
Wr_En <= '0'; |
Wr_Data_q <= (others => '0'); |
Reg_Out <= Default_Value; |
Rd_En <= '0'; |
Rd_Data <= x"00"; |
elsif( rising_edge( Clock ) )then |
Wr_En <= Addr_Match and Wr_Enable; |
Wr_Data_q <= Wr_Data; |
if( Wr_En = '1' )then |
Reg_Out <= Wr_Data_q; |
end if; |
|
Rd_Data <= (others => '0'); |
Rd_En <= Addr_Match and Rd_Enable; |
if( Rd_En = '1' )then |
Rd_Data <= Reg_Out; |
end if; |
|
end if; |
end process; |
|
Register_Out <= Reg_Out; |
|
end architecture; |
open8_urisc/trunk/VHDL/o8_register.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: open8_urisc/trunk/VHDL/o8_status_led.vhd
===================================================================
--- open8_urisc/trunk/VHDL/o8_status_led.vhd (nonexistent)
+++ open8_urisc/trunk/VHDL/o8_status_led.vhd (revision 180)
@@ -0,0 +1,181 @@
+-- Copyright (c)2006, 2016, 2019 Jeremy Seth Henry
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution,
+-- where applicable (as part of a user interface, debugging port, etc.)
+--
+-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
+-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
+-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+-- VHDL Units : o8_status_led
+-- Description: Provides a multi-state status LED controller
+--
+-- Register Map:
+-- Offset Bitfield Description Read/Write
+-- 0x00 -----AAA LED Mode (2:0) (RW)
+--
+-- LED Modes:
+-- 0x00 - LED is fully off
+-- 0x01 - LED is fully on
+-- 0x02 - LED is dimmed to 50%
+-- 0x03 - LED Toggles at 1Hz
+-- 0x04 - LED fades in and out
+--
+-- Revision History
+-- Author Date Change
+------------------ -------- ---------------------------------------------------
+-- Seth Henry 12/20/19 Design Start
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.std_logic_unsigned.all;
+ use ieee.std_logic_arith.all;
+ use ieee.std_logic_misc.all;
+
+library work;
+ use work.open8_pkg.all;
+
+entity o8_status_led is
+generic(
+ Reset_Level : std_logic;
+ Address : ADDRESS_TYPE
+);
+port(
+ Clock : in std_logic;
+ Reset : in std_logic;
+ --
+ Bus_Address : in ADDRESS_TYPE;
+ Wr_Enable : in std_logic;
+ Wr_Data : in DATA_TYPE;
+ Rd_Enable : in std_logic;
+ Rd_Data : out DATA_TYPE;
+ --
+ LED_Out : out std_logic
+);
+end entity;
+
+architecture behave of o8_status_led is
+
+ function ceil_log2 (x : in natural) return natural is
+ variable retval : natural;
+ begin
+ retval := 1;
+ while ((2**retval) - 1) < x loop
+ retval := retval + 1;
+ end loop;
+ return retval;
+ end function;
+
+ constant User_Addr : std_logic_vector(15 downto 0)
+ := Address(15 downto 0);
+ alias Comp_Addr is Bus_Address(15 downto 0);
+ signal Addr_Match : std_logic;
+ signal Wr_En : std_logic;
+ signal Wr_Data_q : std_logic_vector(2 downto 0);
+ signal LED_Mode : std_logic_vector(2 downto 0);
+ signal Rd_En : std_logic;
+
+ signal Dim50Pct_Out : std_logic;
+
+ signal Half_Hz_Timer : std_logic_vector(15 downto 0);
+ constant HALF_HZ_PRD : std_logic_vector(15 downto 0) :=
+ conv_std_logic_vector(500000,16);
+ signal One_Hz_Out : std_logic;
+
+ constant TIMER_MSB : integer range 9 to 20 := 18;
+
+ signal Fade_Timer1 : std_logic_vector(TIMER_MSB downto 0);
+ signal Fade_Timer2 : std_logic_vector(TIMER_MSB downto 0);
+ signal Fade_Out : std_logic;
+
+begin
+
+ Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
+
+ io_reg: process( Clock, Reset )
+ begin
+ if( Reset = Reset_Level )then
+ Wr_En <= '0';
+ Wr_Data_q <= (others => '0');
+ LED_Mode <= (others => '0');
+ Rd_En <= '0';
+ Rd_Data <= x"00";
+ elsif( rising_edge( Clock ) )then
+ Wr_En <= Addr_Match and Wr_Enable;
+ Wr_Data_q <= Wr_Data(2 downto 0);
+ if( Wr_En = '1' )then
+ LED_Mode <= Wr_Data_q;
+ end if;
+
+ Rd_Data <= (others => '0');
+ Rd_En <= Addr_Match and Rd_Enable;
+ if( Rd_En = '1' )then
+ Rd_Data <= "00000" & LED_Mode;
+ end if;
+
+ end if;
+ end process;
+
+ Output_FF: process( Clock, Reset )
+ begin
+ if( Reset = Reset_Level )then
+ LED_Out <= '0';
+ elsif( rising_edge(Clock) )then
+ LED_Out <= '0';
+ case( LED_Mode )is
+ when "001" =>
+ LED_Out <= '1';
+ when "010" =>
+ LED_Out <= Dim50Pct_Out;
+ when "011" =>
+ LED_Out <= One_Hz_Out;
+ when "100" =>
+ LED_Out <= Fade_out;
+ when others => null;
+ end case;
+ end if;
+ end process;
+
+ Timer_proc: process( Clock, Reset )
+ begin
+ if( Reset = Reset_Level )then
+ Dim50Pct_Out <= '0';
+ Half_Hz_Timer <= (others => '0');
+ One_Hz_Out <= '0';
+ Fade_Timer1 <= (others => '0');
+ Fade_Timer2 <= (others => '0');
+ Fade_out <= '0';
+ elsif( rising_edge(Clock) )then
+ Dim50Pct_Out <= not Dim50Pct_Out;
+
+ Half_Hz_Timer <= Half_Hz_Timer - 1;
+ if( Half_Hz_Timer = 0 )then
+ Half_Hz_Timer <= HALF_HZ_PRD;
+ One_Hz_Out <= not One_Hz_Out;
+ end if;
+
+ Fade_Timer1 <= Fade_Timer1 - 1;
+ Fade_Timer2 <= Fade_Timer2 - 1;
+ if( or_reduce(Fade_Timer2) = '0' )then
+ Fade_Timer2(TIMER_MSB downto TIMER_MSB - 8) <= (others => '1');
+ Fade_Timer2(TIMER_MSB - 9 downto 0 ) <= (others => '0');
+ end if;
+ Fade_out <= Fade_Timer1(TIMER_MSB) xor Fade_Timer2(TIMER_MSB);
+ end if;
+ end process;
+
+end architecture;
open8_urisc/trunk/VHDL/o8_status_led.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: open8_urisc/trunk/VHDL/o8_vdsm12.vhd
===================================================================
--- open8_urisc/trunk/VHDL/o8_vdsm12.vhd (nonexistent)
+++ open8_urisc/trunk/VHDL/o8_vdsm12.vhd (revision 180)
@@ -0,0 +1,305 @@
+-- Copyright (c)2019 Jeremy Seth Henry
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution,
+-- where applicable (as part of a user interface, debugging port, etc.)
+--
+-- THIS SOFTWARE IS PROVIDED BY JEREMY SETH HENRY ``AS IS'' AND ANY
+-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+-- DISCLAIMED. IN NO EVENT SHALL JEREMY SETH HENRY BE LIABLE FOR ANY
+-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+-- VHDL Units : o8_vdsm12
+-- Description: 12-bit variable delta-sigma modulator. Requires Open8_pkg.vhd
+--
+-- Register Map:
+-- Offset Bitfield Description Read/Write
+-- 0x0 AAAAAAAA Pending DAC Level (7:0) (R/W)
+-- 0x1 AAAAAAAA Pending DAC Level (11:8) (R/W)
+-- 0x2 -------- Clear DAC Output (on write) (WO)
+-- 0x3 AAAAAAAA Update DAC Output (on write) (RO)
+--
+-- Revision History
+-- Author Date Change
+------------------ -------- ---------------------------------------------------
+-- Seth Henry 12/18/19 Design start
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use ieee.std_logic_arith.all;
+
+library work;
+ use work.open8_pkg.all;
+
+entity o8_vdsm12 is
+generic(
+ Reset_Level : std_logic := '1';
+ Address : ADDRESS_TYPE
+);
+port(
+ Clock : in std_logic;
+ Reset : in std_logic;
+ --
+ Bus_Address : in ADDRESS_TYPE;
+ Wr_Enable : in std_logic;
+ Wr_Data : in DATA_TYPE;
+ Rd_Enable : in std_logic;
+ Rd_Data : out DATA_TYPE;
+ --
+ PDM_Out : out std_logic
+);
+end entity;
+
+architecture behave of o8_vdsm12 is
+
+ function ceil_log2 (x : in natural) return natural is
+ variable retval : natural;
+ begin
+ retval := 1;
+ while ((2**retval) - 1) < x loop
+ retval := retval + 1;
+ end loop;
+ return retval;
+ end function;
+
+ constant User_Addr : std_logic_vector(15 downto 2)
+ := Address(15 downto 2);
+ alias Comp_Addr is Bus_Address(15 downto 2);
+ alias Reg_Addr is Bus_Address(1 downto 0);
+ signal Reg_Sel : std_logic_vector(1 downto 0);
+ signal Addr_Match : std_logic;
+ signal Wr_En : std_logic;
+ signal Wr_Data_q : DATA_TYPE;
+ signal Rd_En : std_logic;
+
+ constant DAC_Width : integer := 12;
+
+ signal DAC_Val_LB : DATA_TYPE;
+ signal DAC_Val_UB : DATA_TYPE;
+ signal DAC_Val : std_logic_vector(DAC_Width-1 downto 0);
+
+ constant DELTA_1_I : integer := 1;
+ constant DELTA_2_I : integer := 5;
+ constant DELTA_3_I : integer := 25;
+ constant DELTA_4_I : integer := 75;
+ constant DELTA_5_I : integer := 125;
+ constant DELTA_6_I : integer := 250;
+ constant DELTA_7_I : integer := 500;
+ constant DELTA_8_I : integer := 1000;
+ constant DELTA_9_I : integer := 2000;
+ constant DELTA_10_I : integer := 3000;
+
+ constant DELTA_1 : std_logic_vector(DAC_Width-1 downto 0) :=
+ conv_std_logic_vector(DELTA_1_I, DAC_Width);
+ constant DELTA_2 : std_logic_vector(DAC_Width-1 downto 0) :=
+ conv_std_logic_vector(DELTA_2_I, DAC_Width);
+ constant DELTA_3 : std_logic_vector(DAC_Width-1 downto 0) :=
+ conv_std_logic_vector(DELTA_3_I, DAC_Width);
+ constant DELTA_4 : std_logic_vector(DAC_Width-1 downto 0) :=
+ conv_std_logic_vector(DELTA_4_I, DAC_Width);
+ constant DELTA_5 : std_logic_vector(DAC_Width-1 downto 0) :=
+ conv_std_logic_vector(DELTA_5_I, DAC_Width);
+ constant DELTA_6 : std_logic_vector(DAC_Width-1 downto 0) :=
+ conv_std_logic_vector(DELTA_6_I, DAC_Width);
+ constant DELTA_7 : std_logic_vector(DAC_Width-1 downto 0) :=
+ conv_std_logic_vector(DELTA_7_I, DAC_Width);
+ constant DELTA_8 : std_logic_vector(DAC_Width-1 downto 0) :=
+ conv_std_logic_vector(DELTA_8_I, DAC_Width);
+ constant DELTA_9 : std_logic_vector(DAC_Width-1 downto 0) :=
+ conv_std_logic_vector(DELTA_9_I, DAC_Width);
+ constant DELTA_10 : std_logic_vector(DAC_Width-1 downto 0) :=
+ conv_std_logic_vector(DELTA_10_I, DAC_Width);
+
+ constant MAX_PERIOD : integer := 2**DAC_Width;
+ constant DIV_WIDTH : integer := DAC_Width * 2;
+
+ constant PADJ_1_I : integer := DELTA_1_I * MAX_PERIOD;
+ constant PADJ_2_I : integer := DELTA_2_I * MAX_PERIOD;
+ constant PADJ_3_I : integer := DELTA_3_I * MAX_PERIOD;
+ constant PADJ_4_I : integer := DELTA_4_I * MAX_PERIOD;
+ constant PADJ_5_I : integer := DELTA_5_I * MAX_PERIOD;
+ constant PADJ_6_I : integer := DELTA_6_I * MAX_PERIOD;
+ constant PADJ_7_I : integer := DELTA_7_I * MAX_PERIOD;
+ constant PADJ_8_I : integer := DELTA_8_I * MAX_PERIOD;
+ constant PADJ_9_I : integer := DELTA_9_I * MAX_PERIOD;
+ constant PADJ_10_I : integer := DELTA_10_I * MAX_PERIOD;
+
+ constant PADJ_1 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
+ conv_std_logic_vector(PADJ_1_I,DIV_WIDTH);
+ constant PADJ_2 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
+ conv_std_logic_vector(PADJ_2_I,DIV_WIDTH);
+ constant PADJ_3 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
+ conv_std_logic_vector(PADJ_3_I,DIV_WIDTH);
+ constant PADJ_4 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
+ conv_std_logic_vector(PADJ_4_I,DIV_WIDTH);
+ constant PADJ_5 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
+ conv_std_logic_vector(PADJ_5_I,DIV_WIDTH);
+ constant PADJ_6 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
+ conv_std_logic_vector(PADJ_6_I,DIV_WIDTH);
+ constant PADJ_7 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
+ conv_std_logic_vector(PADJ_7_I,DIV_WIDTH);
+ constant PADJ_8 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
+ conv_std_logic_vector(PADJ_8_I,DIV_WIDTH);
+ constant PADJ_9 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
+ conv_std_logic_vector(PADJ_9_I,DIV_WIDTH);
+ constant PADJ_10 : std_logic_vector(DIV_WIDTH-1 downto 0) :=
+ conv_std_logic_vector(PADJ_10_I,DIV_WIDTH);
+
+ signal DACin_q : std_logic_vector(DAC_Width-1 downto 0);
+
+ signal Divisor : std_logic_vector(DIV_WIDTH-1 downto 0);
+ signal Dividend : std_logic_vector(DIV_WIDTH-1 downto 0);
+
+ signal q : std_logic_vector(DIV_WIDTH*2-1 downto 0);
+ signal diff : std_logic_vector(DIV_WIDTH downto 0);
+
+ constant CB : integer := ceil_log2(DIV_WIDTH);
+ signal count : std_logic_vector(CB-1 downto 0);
+
+ signal Next_Width : std_logic_vector(DAC_Width-1 downto 0);
+ signal Next_Period : std_logic_vector(DAC_Width-1 downto 0);
+
+ signal PWM_Width : std_logic_vector(DAC_Width-1 downto 0);
+ signal PWM_Period : std_logic_vector(DAC_Width-1 downto 0);
+
+ signal Width_Ctr : std_logic_vector(DAC_Width-1 downto 0);
+ signal Period_Ctr : std_logic_vector(DAC_Width-1 downto 0);
+
+
+begin
+
+ Addr_Match <= '1' when Comp_Addr = User_Addr else '0';
+
+ io_reg: process( Clock, Reset )
+ begin
+ if( Reset = Reset_Level )then
+ Reg_Sel <= "00";
+ Rd_En <= '0';
+ Rd_Data <= x"00";
+ Wr_En <= '0';
+ Wr_Data_q <= x"00";
+ DAC_Val_LB <= x"00";
+ DAC_Val_UB <= x"00";
+ DAC_Val <= (others => '0');
+ elsif( rising_edge( Clock ) )then
+ Reg_Sel <= Reg_Addr;
+
+ Wr_En <= Addr_Match and Wr_Enable;
+ Wr_Data_q <= Wr_Data;
+ if( Wr_En = '1' )then
+ case( Reg_Sel )is
+ when "00" =>
+ DAC_Val_LB <= Wr_Data_q;
+ when "01" =>
+ DAC_Val_UB <= "0000" & Wr_Data_q(3 downto 0);
+ when "10" =>
+ DAC_Val <= (others => '0');
+ when "11" =>
+ DAC_Val <= DAC_Val_UB(3 downto 0) & DAC_Val_LB;
+ when others => null;
+ end case;
+ end if;
+
+ Rd_Data <= (others => '0');
+ Rd_En <= Addr_Match and Rd_Enable;
+ if( Rd_En = '1' )then
+ case( Reg_Sel )is
+ when "00" =>
+ Rd_Data <= DAC_Val_LB;
+ when "01" =>
+ Rd_Data <= DAC_Val_UB;
+ when others => null;
+ end case;
+ end if;
+ end if;
+ end process;
+
+ diff <= ('0' & q(DIV_WIDTH*2-2 downto DIV_WIDTH-1)) -
+ ('0' & Divisor);
+
+ Dividend <= PADJ_2 when DACin_q >= DELTA_2_I and DACin_q < DELTA_3_I else
+ PADJ_3 when DACin_q >= DELTA_3_I and DACin_q < DELTA_4_I else
+ PADJ_4 when DACin_q >= DELTA_4_I and DACin_q < DELTA_5_I else
+ PADJ_5 when DACin_q >= DELTA_5_I and DACin_q < DELTA_6_I else
+ PADJ_6 when DACin_q >= DELTA_6_I and DACin_q < DELTA_7_I else
+ PADJ_7 when DACin_q >= DELTA_7_I and DACin_q < DELTA_8_I else
+ PADJ_8 when DACin_q >= DELTA_8_I and DACin_q < DELTA_9_I else
+ PADJ_9 when DACin_q >= DELTA_9_I and DACin_q < DELTA_10_I else
+ PADJ_10 when DACin_q >= DELTA_10_I else
+ PADJ_1;
+
+ Next_Width <= DELTA_1 when DACin_q >= DELTA_1_I and DACin_q < DELTA_2_I else
+ DELTA_2 when DACin_q >= DELTA_2_I and DACin_q < DELTA_3_I else
+ DELTA_3 when DACin_q >= DELTA_3_I and DACin_q < DELTA_4_I else
+ DELTA_4 when DACin_q >= DELTA_4_I and DACin_q < DELTA_5_I else
+ DELTA_5 when DACin_q >= DELTA_5_I and DACin_q < DELTA_6_I else
+ DELTA_6 when DACin_q >= DELTA_6_I and DACin_q < DELTA_7_I else
+ DELTA_7 when DACin_q >= DELTA_7_I and DACin_q < DELTA_8_I else
+ DELTA_8 when DACin_q >= DELTA_8_I and DACin_q < DELTA_9_I else
+ DELTA_9 when DACin_q >= DELTA_9_I and DACin_q < DELTA_10_I else
+ DELTA_10 when DACin_q >= DELTA_10_I else
+ (others => '0');
+
+ Next_Period <= q(DAC_Width-1 downto 0) - 1;
+
+ vDSM_proc: process( Clock, Reset )
+ begin
+ if( Reset = Reset_Level )then
+ q <= (others => '0');
+ count <= (others => '1');
+ Divisor <= (others => '0');
+ DACin_q <= (others => '0');
+ PWM_Width <= (others => '0');
+ PWM_Period <= (others => '0');
+ Period_Ctr <= (others => '0');
+ Width_Ctr <= (others => '0');
+ PDM_Out <= '0';
+ elsif( rising_edge(Clock) )then
+ q <= diff(DIV_WIDTH-1 downto 0) &
+ q(DIV_WIDTH-2 downto 0) & '1';
+ if( diff(DIV_WIDTH) = '1' )then
+ q <= q(DIV_WIDTH*2-2 downto 0) & '0';
+ end if;
+
+ count <= count + 1;
+ if( count = DIV_WIDTH )then
+ PWM_Width <= Next_Width;
+ PWM_Period <= Next_Period;
+ DACin_q <= DAC_val;
+ Divisor <= (others => '0');
+ Divisor(DAC_Width-1 downto 0) <= DACin_q;
+ q <= conv_std_logic_vector(0,DIV_WIDTH) & Dividend;
+ count <= (others => '0');
+ end if;
+
+ Period_Ctr <= Period_Ctr - 1;
+ Width_Ctr <= Width_Ctr - 1;
+
+ PDM_Out <= '1';
+ if( Width_Ctr = 0 )then
+ PDM_Out <= '0';
+ Width_Ctr <= (others => '0');
+ end if;
+
+ if( Period_Ctr = 0 )then
+ Period_Ctr <= PWM_Period;
+ Width_Ctr <= PWM_Width;
+ end if;
+
+ end if;
+ end process;
+
+end architecture;
open8_urisc/trunk/VHDL/o8_vdsm12.vhd
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property