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
/open8_urisc
- from Rev 323 to Rev 324
- ↔ Reverse comparison
Rev 323 → Rev 324
/trunk/VHDL/o8_mavg_8ch_16b_64d.vhd
30,11 → 30,15
-- 0x00 AAAAAAAA Raw Data (lower) (RW) |
-- 0x01 AAAAAAAA Raw Data (upper) (RW) |
-- 0x02 -----AAA Raw Channel Select (RW) |
-- 0x03 A------- Update Accum / Busy (RW) |
-- 0x03 BA------ Update Accum & Int Enable / Busy (RW*) |
-- 0x04 AAAAAAAA Avg Data (lower) (RW) |
-- 0x05 AAAAAAAA Avg Data (upper) (RW) |
-- 0x06 -----AAA Avg Channel Select (RW) |
-- 0x07 A------- Flush Statistics / Busy (RW) |
-- 0x07 BA------ Flush Statistics & Int_Enable / Busy (RW*) |
-- |
-- Note: Writing bit A high will enable a CPU interrupt for the specified |
-- operation. Writing a low will disable the interrupt. Bit B indicates |
-- the operation status in either case. |
|
library ieee; |
use ieee.std_logic_1164.all; |
47,6 → 51,7
|
entity o8_mavg_8ch_16b_64d is |
generic( |
Autoflush_On_Reset : boolean := TRUE; |
Address : ADDRESS_TYPE |
); |
port( |
87,9 → 92,10
signal Flush_Valid : std_logic := '0'; |
signal Flush_Busy : std_logic := '0'; |
|
type AVG_CTL_STATES is (INIT, CLR_BUFF, IDLE, RD_LAST, ADV_PTR, CALC_NEXT, |
WR_NEW); |
signal AVG_Ctl : AVG_CTL_STATES := INIT; |
type AVG_CTL_STATES is (IDLE, |
RD_LAST, ADV_PTR, CALC_NEXT, WR_NEW, AVG_DONE, |
FLUSH_INIT, FLUSH_RAM, FLUSH_DONE); |
signal AVG_Ctl : AVG_CTL_STATES := FLUSH_INIT; |
|
signal Avg_Busy : std_logic := '0'; |
|
125,6 → 131,9
alias AVG_Out_L is AVG_Out(7 downto 0); |
alias AVG_Out_H is AVG_Out(7 downto 0); |
|
signal AVG_Int_En : std_logic := '0'; |
signal Flush_Int_En : std_logic := '0'; |
|
begin |
|
Addr_Match <= '1' when Comp_Addr = User_Addr else '0'; |
148,6 → 157,8
AVG_Out <= (others => '0'); |
AVG_Channel <= (others => '0'); |
|
AVG_Int_En <= '0'; |
Flush_Int_En <= '0'; |
|
elsif( rising_edge(Clock) )then |
Reg_Sel_q <= Reg_Sel_d; |
154,6 → 165,7
Wr_En_q <= Wr_En_d; |
Wr_Data_q <= Wr_Data_d; |
|
Flush_Valid <= '0'; |
RAW_Valid <= '0'; |
|
if( Wr_En_q = '1' )then |
168,13 → 180,15
RAW_Channel <= Wr_Data_q(2 downto 0); |
|
when "011" => |
RAW_Valid <= not Avg_Busy; |
AVG_Int_En <= Wr_Data_q(6); |
RAW_Valid <= not (Flush_Busy or Avg_Busy); |
|
when "110" => |
AVG_Channel <= Wr_Data_q(2 downto 0); |
|
when "111" => |
Flush_Valid <= not Flush_Busy; |
Flush_Int_En <= Wr_Data_q(6); |
Flush_Valid <= not (Flush_Busy or Avg_Busy); |
|
when others => |
null; |
199,7 → 213,7
Rd_Data <= "00000" & RAW_Channel; |
|
when "011" => |
Rd_Data <= Avg_Busy & "0000000"; |
Rd_Data <= Avg_Busy & AVG_Int_En & "000000"; |
|
when "100" => |
Rd_Data <= AVG_Out_L; |
211,7 → 225,7
Rd_Data <= "00000" & AVG_Channel; |
|
when "111" => |
Rd_Data <= Flush_Busy & "0000000"; |
Rd_Data <= Flush_Busy & Flush_Int_En & "000000"; |
|
when others => |
null; |
226,7 → 240,10
variable i : integer := 0; |
begin |
if( Reset = Reset_Level )then |
AVG_Ctl <= INIT; |
AVG_Ctl <= IDLE; |
if( Autoflush_On_Reset )then |
AVG_Ctl <= FLUSH_INIT; |
end if; |
|
CH_Select <= (others => '0'); |
Data_New <= (others => '0'); |
254,29 → 271,14
RAM_Wr_En <= '0'; |
|
Flush_Busy <= '0'; |
Avg_Busy <= '1'; |
Avg_Busy <= '0'; |
|
i := conv_integer(unsigned(CH_Select)); |
|
case( AVG_Ctl )is |
when INIT => |
Flush_Busy <= '1'; |
RAM_Wr_Addr <= (others => '0'); |
RAM_Wr_Data <= (others => '0'); |
AVG_Ctl <= CLR_BUFF; |
|
when CLR_BUFF => |
Flush_Busy <= '1'; |
RAM_Wr_Addr <= RAM_Wr_Addr + 1; |
RAM_Wr_En <= '1'; |
if( and_reduce(RAM_Wr_Addr) = '1' )then |
AVG_Ctl <= IDLE; |
end if; |
|
when IDLE => |
Avg_Busy <= '0'; |
if( Flush_Valid = '1' )then |
AVG_Ctl <= INIT; |
AVG_Ctl <= FLUSH_INIT; |
elsif( RAW_Valid = '1' )then |
Data_New <= RAW_Data; |
CH_Select <= RAW_Channel; |
283,16 → 285,20
AVG_Ctl <= RD_LAST; |
end if; |
|
-- Data Average Update States |
when RD_LAST => |
Avg_Busy <= '1'; |
RAM_Rd_Chan <= CH_Select; |
RAM_Rd_Ptr <= SPN_Pointers(i); |
AVG_Ctl <= ADV_PTR; |
|
when ADV_PTR => |
Avg_Busy <= '1'; |
SP0_Pointers(i) <= SP0_Pointers(i) + 1; |
AVG_Ctl <= CALC_NEXT; |
|
when CALC_NEXT => |
Avg_Busy <= '1'; |
Accumulators(i) <= Accumulators(i) + |
unsigned( Data_New ) - |
unsigned( Data_Old ); |
299,14 → 305,37
AVG_Ctl <= WR_NEW; |
|
when WR_NEW => |
Avg_Busy <= '1'; |
RAM_Wr_Chan <= CH_Select; |
RAM_Wr_Ptr <= SP0_Pointers(i); |
RAM_Wr_Data <= Data_New; |
RAM_Wr_En <= '1'; |
SPN_Pointers(i) <= SP0_Pointers(i) + 1; |
Interrupt <= '1'; |
AVG_Ctl <= AVG_DONE; |
|
when AVG_DONE => |
Interrupt <= AVG_Int_En; |
AVG_Ctl <= IDLE; |
|
-- Buffer Flush States |
when FLUSH_INIT => |
Flush_Busy <= '1'; |
RAM_Wr_Addr <= (others => '0'); |
RAM_Wr_Data <= (others => '0'); |
AVG_Ctl <= FLUSH_RAM; |
|
when FLUSH_RAM => |
Flush_Busy <= '1'; |
RAM_Wr_Addr <= RAM_Wr_Addr + 1; |
RAM_Wr_En <= '1'; |
if( and_reduce(RAM_Wr_Addr) = '1' )then |
AVG_Ctl <= FLUSH_DONE; |
end if; |
|
when FLUSH_DONE => |
Interrupt <= Flush_Int_En; |
AVG_Ctl <= IDLE; |
|
when others => |
null; |
end case; |
/trunk/VHDL/o8_romtape_8k.vhd
0,0 → 1,172
-- Copyright (c)2023 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_romtape_8k |
-- Description: Provides serial FIFO-like access to an 8k ROM with settable |
-- : start address and increment. Automatically increments on |
-- : read. |
-- : This allows for bulk data to be accessed without using up |
-- : large amounts of address space, such as text strings or |
-- : configuration parameters. |
-- |
-- : Note 1: The ROM Position register tracks the internal |
-- : address, and will change once the ROM is accessed. |
-- |
-- : Note 2: The ROM Address Auto-Increment value is a signed |
-- : offset. This implies that the auto-increment varies from |
-- : -128 to 127. |
-- : A value of 0x00 will disable the auto-increment function. |
|
-- WP Register Map: |
-- Offset Bitfield Description Read/Write |
-- 0x00 AAAAAAAA ROM Data (RO) |
-- 0x01 AAAAAAAA ROM Address Auto-Increment (RW) |
-- 0x02 AAAAAAAA ROM Position (lower) (RW) |
-- 0x03 ---AAAAA ROM Position (upper) (RW) |
-- |
-- Revision History |
-- Author Date Change |
------------------ -------- --------------------------------------------------- |
-- Seth Henry 07/18/23 Initial Design |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_signed.all; |
use ieee.std_logic_arith.all; |
|
library work; |
use work.open8_pkg.all; |
|
entity o8_romtape_8k is |
generic( |
Address : ADDRESS_TYPE |
); |
port( |
Open8_Bus : in OPEN8_BUS_TYPE; |
Write_Qual : in std_logic := '1'; |
Rd_Data : out DATA_TYPE |
); |
end entity; |
|
architecture behave of o8_romtape_8k is |
|
alias Clock is Open8_Bus.Clock; |
alias Reset is Open8_Bus.Reset; |
|
constant User_Addr : std_logic_vector(15 downto 2) |
:= Address(15 downto 2); |
alias Comp_Addr is Open8_Bus.Address(15 downto 2); |
signal Addr_Match : std_logic; |
|
alias Reg_Addr is Open8_Bus.Address(1 downto 0); |
signal Reg_Sel : std_logic_vector(1 downto 0); |
|
signal Wr_En : std_logic := '0'; |
signal Wr_Data : DATA_TYPE := OPEN8_NULLBUS; |
signal Rd_En : std_logic := '0'; |
|
signal Address_Ptr : signed(12 downto 0); |
alias Address_Ptr_L is Address_Ptr(7 downto 0); |
alias Address_Ptr_H is Address_Ptr(12 downto 8); |
|
signal Address_Incr : signed(12 downto 0); |
alias Address_Incr_L is Address_Incr(7 downto 0); |
alias Address_Incr_H is Address_Incr(12 downto 8); |
|
constant DEFLT_INCR : signed(12 downto 0) := |
conv_signed(1,13); |
|
signal ROM_Ptr : std_logic_vector(12 downto 0); |
signal ROM_Data : std_logic_vector(7 downto 0); |
|
begin |
|
-- Due to reads altering the state of the entity, all access should be |
-- qualified by Write_Qual |
Addr_Match <= Write_Qual when Comp_Addr = User_Addr else '0'; |
|
Reg_proc: process( Reset, Clock ) |
begin |
if( Reset = Reset_Level )then |
|
Address_Ptr <= (others => '0'); |
Address_Incr <= DEFLT_INCR; |
|
Reg_Sel <= (others => '0'); |
Wr_En <= '0'; |
Wr_Data <= OPEN8_NULLBUS; |
Rd_En <= '0'; |
|
Rd_Data <= OPEN8_NULLBUS; |
|
elsif( rising_edge(Clock) )then |
Reg_Sel <= Reg_Addr; |
|
Wr_En <= Addr_Match and Open8_Bus.Wr_En; |
Wr_Data <= Open8_Bus.Wr_Data; |
if( Wr_en = '1' )then |
case( Reg_Sel )is |
when "01" => |
Address_Incr_L <= signed(Wr_Data); |
Address_Incr_H <= (others => Wr_Data(7)); |
when "10" => |
Address_Ptr_L <= signed(Wr_Data); |
when "11" => |
Address_Ptr_H <= signed(Wr_Data(4 downto 0)); |
when others => |
null; |
end case; |
end if; |
|
Rd_En <= Addr_Match and Open8_Bus.Rd_En; |
|
Rd_Data <= OPEN8_NULLBUS; |
if( Rd_En = '1' )then |
case( Reg_Sel )is |
when "00" => |
Rd_Data <= ROM_Data; |
Address_Ptr <= Address_Ptr + Address_Incr; |
when "01" => |
Rd_Data <= std_logic_vector(Address_Incr_L); |
when "10" => |
Rd_Data <= ROM_Ptr(7 downto 0); |
when "11" => |
Rd_Data <= "000" & ROM_Ptr(12 downto 8); |
when others => |
null; |
end case; |
end if; |
|
end if; |
end process; |
|
ROM_Ptr <= std_logic_vector(Address_Ptr); |
|
U_ROM : entity work.rom_8k_core |
port map( |
address => ROM_Ptr, |
clock => Clock, |
q => ROM_Data |
); |
|
end architecture; |