OpenCores
URL https://opencores.org/ocsvn/wb_vga/wb_vga/trunk

Subversion Repositories wb_vga

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

/tags/a01/TestBench/vga_chip_TB.vhd
0,0 → 1,309
library ieee,exemplar;
use ieee.std_logic_1164.all;
use exemplar.exemplar_1164.all;
 
entity vga_chip_tb is
-- Generic declarations of the tested unit
generic(
v_mem_width : POSITIVE := 16;
fifo_size : POSITIVE := 256;
v_addr_width : POSITIVE := 20 );
end vga_chip_tb;
 
architecture TB of vga_chip_tb is
-- Component declaration of the tested unit
component vga_chip
port (
clk_i: in std_logic;
clk_en: in std_logic := '1';
rst_i: in std_logic := '0';
-- CPU bus interface
dat_i: in std_logic_vector (8-1 downto 0);
dat_oi: in std_logic_vector (8-1 downto 0);
dat_o: out std_logic_vector (8-1 downto 0);
cyc_i: in std_logic;
ack_o: out std_logic;
ack_oi: in std_logic;
we_i: in std_logic;
vmem_stb_i: in std_logic;
reg_stb_i: in std_logic;
adr_i: in std_logic_vector (20 downto 0);
-- video memory SRAM interface
s_data : inout std_logic_vector((16-1) downto 0);
s_addr : out std_logic_vector((20-1) downto 0);
s_oen : out std_logic;
s_wrhn : out std_logic;
s_wrln : out std_logic;
s_cen : out std_logic;
-- sync blank and video signal outputs
h_sync: out std_logic;
h_blank: out std_logic;
v_sync: out std_logic;
v_blank: out std_logic;
h_tc: out std_logic;
v_tc: out std_logic;
blank: out std_logic;
video_out: out std_logic_vector (7 downto 0) -- video output binary signal (unused bits are forced to 0)
);
end component;
 
-- Stimulus signals - signals mapped to the input and inout ports of tested entity
signal clk_i : std_logic;
signal clk_en : std_logic;
signal rst_i : std_logic;
signal dat_i : std_logic_vector(7 downto 0);
signal dat_oi : std_logic_vector(7 downto 0);
signal cyc_i : std_logic;
signal ack_oi : std_logic;
signal we_i : std_logic;
signal vmem_stb_i : std_logic;
signal reg_stb_i : std_logic;
signal adr_i : std_logic_vector(v_addr_width downto 0);
signal s_data : std_logic_vector((v_mem_width-1) downto 0);
-- Observed signals - signals mapped to the output ports of tested entity
signal dat_o : std_logic_vector(7 downto 0);
signal ack_o : std_logic;
signal s_addr : std_logic_vector((v_addr_width-1) downto 0);
signal s_oen : std_logic;
signal s_wrhn : std_logic;
signal s_wrln : std_logic;
signal s_cen : std_logic;
signal h_sync : std_logic;
signal h_blank : std_logic;
signal v_sync : std_logic;
signal v_blank : std_logic;
signal h_tc : std_logic;
signal v_tc : std_logic;
signal blank : std_logic;
signal video_out : std_logic_vector(7 downto 0);
 
constant reg_total0 : std_logic_vector(v_addr_width downto 0) := "000000000000000000000";
constant reg_total1 : std_logic_vector(v_addr_width downto 0) := "000000000000000000001";
constant reg_total2 : std_logic_vector(v_addr_width downto 0) := "000000000000000000010";
constant reg_fifo_treshold : std_logic_vector(v_addr_width downto 0) := "000000000000000000011";
constant reg_hbs : std_logic_vector(v_addr_width downto 0) := "000000000000000000100";
constant reg_hss : std_logic_vector(v_addr_width downto 0) := "000000000000000000101";
constant reg_hse : std_logic_vector(v_addr_width downto 0) := "000000000000000000110";
constant reg_htotal : std_logic_vector(v_addr_width downto 0) := "000000000000000000111";
constant reg_vbs : std_logic_vector(v_addr_width downto 0) := "000000000000000001000";
constant reg_vss : std_logic_vector(v_addr_width downto 0) := "000000000000000001001";
constant reg_vse : std_logic_vector(v_addr_width downto 0) := "000000000000000001010";
constant reg_vtotal : std_logic_vector(v_addr_width downto 0) := "000000000000000001011";
constant reg_pps : std_logic_vector(v_addr_width downto 0) := "000000000000000001100";
constant reg_ws : std_logic_vector(v_addr_width downto 0) := "000000000000000001101";
constant reg_bpp : std_logic_vector(v_addr_width downto 0) := "000000000000000001110";
constant val_total0 : std_logic_vector(7 downto 0) := "00001111";
constant val_total1 : std_logic_vector(7 downto 0) := "00000000";
constant val_total2 : std_logic_vector(7 downto 0) := "00000000";
constant val_fifo_treshold : std_logic_vector(7 downto 0) := "00000011";
constant val_hbs : std_logic_vector(7 downto 0) := "00000111";
constant val_hss : std_logic_vector(7 downto 0) := "00001000";
constant val_hse : std_logic_vector(7 downto 0) := "00001001";
constant val_htotal : std_logic_vector(7 downto 0) := "00001010";
constant val_vbs : std_logic_vector(7 downto 0) := "00000001";
constant val_vss : std_logic_vector(7 downto 0) := "00000010";
constant val_vse : std_logic_vector(7 downto 0) := "00000011";
constant val_vtotal : std_logic_vector(7 downto 0) := "00000100";
constant val_pps : std_logic_vector(7 downto 0) := "00000001";
constant val_ws : std_logic_vector(7 downto 0) := "00010010";
-- constant val_bpp : std_logic_vector(7 downto 0) := "00000001";
constant val_bpp : std_logic_vector(7 downto 0) := "00000011";
-- Add your code here ...
procedure chk_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR(v_addr_width downto 0);
signal dat_o: in STD_LOGIC_VECTOR(7 downto 0);
signal dat_i: out STD_LOGIC_VECTOR(7 downto 0);
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in STD_LOGIC_VECTOR(v_addr_width downto 0);
constant data: in STD_LOGIC_VECTOR(7 downto 0)
) is
begin
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
adr_i <= addr;
dat_i <= (others => '0');
cyc_i <= '1';
stb_i <= '1';
we_i <= '0';
wait until clk_i'EVENT and clk_i = '1' and ack_o = '1';
assert dat_o = data report "Value does not match!" severity ERROR;
adr_i <= (others => '0');
stb_i <= '0';
cyc_i <= '0';
end procedure;
procedure write_val(
signal clk_i: in STD_LOGIC;
signal adr_i: out STD_LOGIC_VECTOR(v_addr_width downto 0);
signal dat_o: in STD_LOGIC_VECTOR(7 downto 0);
signal dat_i: out STD_LOGIC_VECTOR(7 downto 0);
signal we_i: out STD_LOGIC;
signal cyc_i: out std_logic;
signal stb_i: out STD_LOGIC;
signal ack_o: in STD_LOGIC;
constant addr: in STD_LOGIC_VECTOR(v_addr_width downto 0);
constant data: in STD_LOGIC_VECTOR(7 downto 0)
) is
begin
adr_i <= (others => '0');
dat_i <= (others => '0');
stb_i <= '0';
we_i <= '0';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
adr_i <= addr;
dat_i <= data;
cyc_i <= '1';
stb_i <= '1';
we_i <= '1';
wait until clk_i'EVENT and clk_i = '1' and ack_o = '1';
adr_i <= (others => '0');
dat_i <= (others => '0');
cyc_i <= '0';
stb_i <= '0';
we_i <= '0';
end procedure;
begin
 
-- Unit Under Test port map
UUT : vga_chip
port map (
clk_i => clk_i,
clk_en => clk_en,
rst_i => rst_i,
dat_i => dat_i,
dat_oi => dat_oi,
dat_o => dat_o,
cyc_i => cyc_i,
ack_o => ack_o,
ack_oi => ack_oi,
we_i => we_i,
vmem_stb_i => vmem_stb_i,
reg_stb_i => reg_stb_i,
adr_i => adr_i,
s_data => s_data,
s_addr => s_addr,
s_oen => s_oen,
s_wrhn => s_wrhn,
s_wrln => s_wrln,
s_cen => s_cen,
h_sync => h_sync,
h_blank => h_blank,
v_sync => v_sync,
v_blank => v_blank,
h_tc => h_tc,
v_tc => v_tc,
blank => blank,
video_out => video_out
);
 
-- Add your stimulus here ...
 
clk_en <= '1';
-- Add your stimulus here ...
clock: process is
begin
wait for 25 ns;
clk_i <= '1';
wait for 25 ns;
clk_i <= '0';
end process;
ack_oi <= '0';
dat_oi <= (others => '0');
setup: process is
begin
we_i <= '0';
reg_stb_i <= '0';
vmem_stb_i <= '0';
rst_i <= '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
rst_i <= '0';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total0 ,val_total0);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total1 ,val_total1);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total2 ,val_total2);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_fifo_treshold ,val_fifo_treshold);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hbs ,val_hbs);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hss ,val_hss);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hse ,val_hse);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_htotal ,val_htotal);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vbs ,val_vbs);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vss ,val_vss);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vse ,val_vse);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vtotal ,val_vtotal);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_pps ,val_pps);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ws ,val_ws);
write_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_bpp ,val_bpp);
 
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
wait until clk_i'EVENT and clk_i = '1';
 
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total0 ,val_total0);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total1 ,val_total1);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_total2 ,val_total2);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_fifo_treshold ,val_fifo_treshold);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hbs ,val_hbs);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hss ,val_hss);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_hse ,val_hse);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_htotal ,val_htotal);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vbs ,val_vbs);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vss ,val_vss);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vse ,val_vse);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_vtotal ,val_vtotal);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_pps ,val_pps);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_ws ,val_ws);
chk_val(clk_i, adr_i,dat_o,dat_i,we_i,cyc_i,reg_stb_i,ack_o,reg_bpp ,val_bpp);
wait;
end process;
 
s_ram: process is
begin
wait on s_data,s_addr,s_oen,s_wrhn,s_wrln,s_cen;
if (s_cen = '0') then
if (s_oen = '0') then
s_data <= s_addr(v_mem_width-1 downto 0);
elsif (s_wrhn = '0' or s_wrln = '0') then
if (s_wrhn = '0') then
else
end if;
else
s_data <= (others => 'Z');
end if;
end if;
end process;
end TB;
 
configuration TB_vga_chip of vga_chip_tb is
for TB
for UUT : vga_chip
use entity work.vga_chip(vga_chip);
end for;
end for;
end TB_vga_chip;
 
/tags/a01/gpl.txt
0,0 → 1,221
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
 
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
 
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
 
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
 
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
 
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
 
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
 
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
 
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
 
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
 
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
 
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
 
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
 
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
 
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
 
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
 
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
 
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
 
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
 
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
 
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
 
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
 
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
 
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
 
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
 
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
 
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
 
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
 
NO WARRANTY
 
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
 
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
 
/tags/a01/mem_reader.vhd
0,0 → 1,347
--
-- File: mem_reader.vhd
--
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31
-- This code is distributed under the terms and conditions of the GNU General Public Lince.
--
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library work;
use work.technology.all;
 
entity mem_reader is
generic (
v_mem_width: positive := 16;
v_addr_width: positive:= 20;
fifo_size: positive := 256;
dual_scan_fifo_size: positive := 256
);
port (
clk: in std_logic;
clk_en: in std_logic;
pix_clk_en: in std_logic;
reset: in std_logic := '0';
total: in std_logic_vector(v_addr_width-1 downto 0); -- total video memory size in bytes 7..0
fifo_treshold: in std_logic_vector(7 downto 0); -- priority change threshold
bpp: in std_logic_vector(1 downto 0); -- number of bits makes up a pixel valid values: 1,2,4,8
multi_scan: in std_logic_vector(1 downto 0); -- number of repeated scans
 
-- Can be githces on it!!! Don't clock by it!!!
high_prior: out std_logic; -- signals to the memory arbitrer to give high
-- priority to the video engine
v_mem_rd: out std_logic; -- video memory read request
v_mem_rdy: in std_logic; -- video memory data ready
v_mem_addr: out std_logic_vector (v_addr_width-1 downto 0); -- video memory address
v_mem_data: in std_logic_vector (v_mem_width-1 downto 0); -- video memory data
 
blank: in std_logic; -- video sync generator blank output
h_tc: in std_logic; -- horizontal sync pulse. Must be 1 clock wide!
video_out: out std_logic_vector (7 downto 0) -- video output binary signal (unused bits are forced to 0)
);
end mem_reader;
 
architecture mem_reader of mem_reader is
component fifo
generic (fifo_width : positive;
used_width : positive;
fifo_depth : positive
);
port (d_in : in std_logic_vector(fifo_width-1 downto 0);
clk : in std_logic;
wr : in std_logic;
rd : in std_logic;
a_clr : in std_logic := '0';
s_clr : in std_logic := '0';
d_out : out std_logic_vector(fifo_width-1 downto 0);
used : out std_logic_vector(used_width-1 downto 0);
full : out std_logic;
empty : out std_logic
);
end component;
 
signal fifo_rd: std_logic;
signal fifo_out: std_logic_vector(v_mem_width-1 downto 0);
 
signal video_fifo_out: std_logic_vector(v_mem_width-1 downto 0);
signal video_fifo_usedw: std_logic_vector(7 downto 0);
signal video_fifo_rd: std_logic;
signal video_fifo_full: std_logic;
signal video_fifo_empty: std_logic;
signal ds_fifo_out: std_logic_vector(v_mem_width-1 downto 0);
-- signal ds_fifo_usedw: std_logic_vector(7 downto 0);
signal ds_fifo_rd: std_logic;
signal ds_fifo_clr: std_logic;
-- signal ds_fifo_full: std_logic;
-- signal ds_fifo_empty: std_logic;
signal i_video_out: std_logic_vector(7 downto 0);
signal ds_mode: std_logic;
 
subtype pixel_cntr_var is integer range 0 to 7;
-- signal i_v_mem_rd: std_logic := '0';
begin
-- memory decoupler FIFO
pixel_fifo: fifo
generic map (
fifo_width => v_mem_width,
used_width => 8,
fifo_depth => fifo_size
)
port map (
d_in => v_mem_data,
clk => clk,
wr => v_mem_rdy,
rd => video_fifo_rd,
-- a_clr => '0',
a_clr => reset,
s_clr => reset,
full => video_fifo_full,
d_out => video_fifo_out,
used => video_fifo_usedw,
empty => video_fifo_empty
);
-- dual-scan FIFO
ds_pixel_fifo: fifo
generic map (
fifo_width => v_mem_width,
used_width => 8,
fifo_depth => dual_scan_fifo_size
)
port map (
d_in => fifo_out,
clk => clk,
wr => fifo_rd,
rd => ds_fifo_rd,
-- a_clr => '0',
a_clr => reset,
s_clr => ds_fifo_clr,
d_out => ds_fifo_out
);
-- Multiplexer for DS data handling
fifo_mux: for i in v_mem_width-1 downto 0 generate
begin
fifo_out(i) <= (video_fifo_out(i) and not ds_mode) or (ds_fifo_out(i) and ds_mode);
-- fifo_out(i) <= (video_fifo_out(i) and not ds_mode);
end generate;
--fifo_out <= (video_fifo_out and not ds_mode);
ds_fifo_rd <= ('0' and not ds_mode) or (fifo_rd and ds_mode);
video_fifo_rd <= (fifo_rd and not ds_mode) or ('0' and ds_mode);
-- Counter handles DS
ds_counter : process is
variable cnt: std_logic_vector(1 downto 0);
begin
wait until clk'EVENT and clk = '1';
if (reset = '1') then
cnt := (others => '0');
ds_fifo_clr <= '1';
ds_mode <= '0';
else
if (clk_en = '1') then
if (h_tc = '1') then
if (is_zero(cnt)) then
ds_mode <= '0';
ds_fifo_clr <= '1';
else
ds_mode <= '1';
ds_fifo_clr <= '0';
end if;
if (cnt = multi_scan) then
cnt := (others => '0');
else
cnt := add_one(cnt);
end if;
else
ds_fifo_clr <= '0';
end if;
else
ds_fifo_clr <= '1';
ds_mode <= '0';
end if;
end if;
end process;
-- Pixel data reader state machine
pixel_cntr : process is
variable pixel_cnt: std_logic_vector(v_addr_width-1 downto 0);
begin
wait until clk'EVENT and clk='1';
if (reset = '1') then
pixel_cnt := (others => '0');
else
-- A little cheet. It won't work with constant v_mem_rdy.
if (v_mem_rdy = '1') then
-- data is already written to the FIFO, all we need to do is to update the counter,
-- and remove the request
if (pixel_cnt = total) then
pixel_cnt := (others => '0');
else
pixel_cnt := add_one(pixel_cnt);
end if;
end if;
end if;
v_mem_addr <= pixel_cnt;
end process;
v_mem_rd <= not video_fifo_full;
 
-- Pixel data output state machine.
pixel_output: process is
subtype pixel_cntr_var is integer range 0 to v_mem_width-1;
 
variable pixel_cntr : pixel_cntr_var;
variable shift_reg : std_logic_vector (v_mem_width-1 downto 0);
type rst_states is (in_reset,read,normal);
variable rst_state : rst_states := in_reset;
begin
wait until clk'EVENT and clk='1';
if (reset = '1') then
fifo_rd <= '0';
i_video_out <= (others => '0');
shift_reg := (others => '0');
pixel_cntr := 0;
rst_state := in_reset;
else
if (not (rst_state = normal)) then
-- perform one read after reset otherwise the picture will be shifted rigth one pixel
case (rst_state) is
when in_reset =>
if (video_fifo_empty = '0') then
fifo_rd <= '1';
rst_state := read;
else
fifo_rd <= '0';
end if;
when read =>
pixel_cntr := 0;
shift_reg := fifo_out;
fifo_rd <= '0';
rst_state := normal;
when others =>
end case;
else
if (pix_clk_en = '0') then
fifo_rd <= '0'; -- clear any pending read requests
else
if (blank = '1') then
fifo_rd <= '0'; -- clear any pending read requests
i_video_out <= (others => '0'); -- disable output
-- i_video_out <= (others => 'U'); -- disable output
else
case (bpp) is
when "00" =>
-- shift next data to the output and optionally read the next data from the fifo
i_video_out(0) <= shift_reg(v_mem_width-1);
i_video_out(7 downto 1) <= (others => '0');
if (pixel_cntr = v_mem_width-1) then
-- Read next data
pixel_cntr := 0;
shift_reg := fifo_out;
fifo_rd <= '0';
elsif (pixel_cntr = v_mem_width-2) then
-- Request next data from FIFO
pixel_cntr := pixel_cntr + 1;
fifo_rd <= '1';
shift_reg := sl(shift_reg,1);
else
-- Simple increment
pixel_cntr := pixel_cntr + 1;
fifo_rd <= '0';
shift_reg := sl(shift_reg,1);
end if;
when "01" =>
-- shift next data to the output and optionally read the next data from the fifo
i_video_out(1 downto 0) <= shift_reg(v_mem_width-1 downto v_mem_width-2);
i_video_out(7 downto 2) <= (others => '0');
if (pixel_cntr = v_mem_width/2-1) then
-- Read next data
pixel_cntr := 0;
shift_reg := fifo_out;
fifo_rd <= '0';
elsif (pixel_cntr = v_mem_width/2-2) then
-- Request next data from FIFO
pixel_cntr := pixel_cntr + 1;
fifo_rd <= '1';
shift_reg := sl(shift_reg,2);
else
-- Simple increment
pixel_cntr := pixel_cntr + 1;
fifo_rd <= '0';
shift_reg := sl(shift_reg,2);
end if;
when "10" =>
-- shift next data to the output and optionally read the next data from the fifo
i_video_out(3 downto 0) <= shift_reg(v_mem_width-1 downto v_mem_width-4);
i_video_out(7 downto 4) <= (others => '0');
if (pixel_cntr = v_mem_width/4-1) then
-- Read next data
pixel_cntr := 0;
shift_reg := fifo_out;
fifo_rd <= '0';
elsif (pixel_cntr = v_mem_width/4-2) then
-- Request next data from FIFO
pixel_cntr := pixel_cntr + 1;
fifo_rd <= '1';
shift_reg := sl(shift_reg,4);
else
-- Simple increment
pixel_cntr := pixel_cntr + 1;
fifo_rd <= '0';
shift_reg := sl(shift_reg,4);
end if;
when "11" =>
if (v_mem_width = 8) then
-- 8 bit memory with 8 bit output: every clock reads a byte from the fifo.
fifo_rd <= '1';
i_video_out(7 downto 0) <= fifo_out;
else
-- shift next data to the output and optionally read the next data from the fifo
i_video_out(7 downto 0) <= shift_reg(v_mem_width-1 downto v_mem_width-8);
if (pixel_cntr = v_mem_width/8-1) then
-- Read next data
pixel_cntr := 0;
shift_reg := fifo_out;
fifo_rd <= '0';
elsif (pixel_cntr = v_mem_width/8-2) then
-- Request next data from FIFO
pixel_cntr := pixel_cntr + 1;
fifo_rd <= '1';
shift_reg := sl(shift_reg,8);
else
-- Simple increment
pixel_cntr := pixel_cntr + 1;
fifo_rd <= '0';
shift_reg := sl(shift_reg,8);
end if;
end if;
when others => -- Unsupported setting. Do nothing
i_video_out(7 downto 0) <= (others => '0');
fifo_rd <= '0';
pixel_cntr := 0;
end case;
end if;
end if;
end if;
end if;
end process;
 
video_out <= i_video_out;
-- Simple logic generates the high_prior output
priority: process is
begin
wait on video_fifo_usedw,fifo_treshold,video_fifo_full;
if (video_fifo_usedw < fifo_treshold and video_fifo_full = '0') then
high_prior <= '1';
else
high_prior <= '0';
end if;
end process;
end mem_reader;
/tags/a01/vga_chip.vhd
0,0 → 1,152
--
-- File: vga_chip.vhd
--
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31
-- This code is distributed under the terms and conditions of the GNU General Public Lince.
--
 
library IEEE;
use IEEE.std_logic_1164.all;
 
-- same as VGA_CORE but without generics. Suited for post-layout simulation.
entity vga_chip is
port (
clk_i: in std_logic;
clk_en: in std_logic := '1';
rst_i: in std_logic := '0';
 
-- CPU bus interface
dat_i: in std_logic_vector (8-1 downto 0);
dat_oi: in std_logic_vector (8-1 downto 0);
dat_o: out std_logic_vector (8-1 downto 0);
cyc_i: in std_logic;
ack_o: out std_logic;
ack_oi: in std_logic;
we_i: in std_logic;
vmem_stb_i: in std_logic;
reg_stb_i: in std_logic;
adr_i: in std_logic_vector (20 downto 0);
 
-- video memory SRAM interface
s_data : inout std_logic_vector((16-1) downto 0);
s_addr : out std_logic_vector((20-1) downto 0);
s_oen : out std_logic;
s_wrhn : out std_logic;
s_wrln : out std_logic;
s_cen : out std_logic;
 
-- sync blank and video signal outputs
h_sync: out std_logic;
h_blank: out std_logic;
v_sync: out std_logic;
v_blank: out std_logic;
h_tc: out std_logic;
v_tc: out std_logic;
blank: out std_logic;
video_out: out std_logic_vector (7 downto 0); -- video output binary signal (unused bits are forced to 0)
 
-- TEST SIGNALS
T_v_we_o: out std_logic;
T_v_stb_o: out std_logic;
T_v_ack_i: out std_logic;
T_v_adr_o : out std_logic_vector((20-1) downto 0);
T_v_sel_o : out std_logic_vector((16/8)-1 downto 0);
T_v_dat_o : out std_logic_vector((16-1) downto 0);
T_v_dat_i : out std_logic_vector((16-1) downto 0)
);
end vga_chip;
 
architecture vga_chip of vga_chip is
component vga_core
generic (
-- cannot be overwritten at the moment...
v_mem_width: positive := 16;
fifo_size: positive := 256;
v_addr_width : positive := 20;
bus_width: positive := 8
);
port (
clk_i: in std_logic;
clk_en: in std_logic := '1';
rst_i: in std_logic := '0';
-- CPU bus interface
dat_i: in std_logic_vector (bus_width-1 downto 0);
dat_oi: in std_logic_vector (bus_width-1 downto 0);
dat_o: out std_logic_vector (bus_width-1 downto 0);
cyc_i: in std_logic;
ack_o: out std_logic;
ack_oi: in std_logic;
we_i: in std_logic;
vmem_stb_i: in std_logic;
reg_stb_i: in std_logic;
adr_i: in std_logic_vector (v_addr_width downto 0);
-- video memory SRAM interface
s_data : inout std_logic_vector((v_mem_width-1) downto 0);
s_addr : out std_logic_vector((v_addr_width-1) downto 0);
s_oen : out std_logic;
s_wrhn : out std_logic;
s_wrln : out std_logic;
s_cen : out std_logic;
-- sync blank and video signal outputs
h_sync: out std_logic;
h_blank: out std_logic;
v_sync: out std_logic;
v_blank: out std_logic;
h_tc: out std_logic;
v_tc: out std_logic;
blank: out std_logic;
video_out: out std_logic_vector (7 downto 0); -- video output binary signal (unused bits are forced to 0)
 
-- TEST SIGNALS
T_v_we_o: out std_logic;
T_v_stb_o: out std_logic;
T_v_ack_i: out std_logic;
T_v_adr_o : out std_logic_vector((v_addr_width-1) downto 0);
T_v_sel_o : out std_logic_vector((v_addr_width/8)-1 downto 0);
T_v_dat_o : out std_logic_vector((v_mem_width-1) downto 0);
T_v_dat_i : out std_logic_vector((v_mem_width-1) downto 0)
);
end component;
begin
Core : vga_core
port map (
clk_i => clk_i,
clk_en => clk_en,
rst_i => rst_i,
dat_i => dat_i,
dat_oi => dat_oi,
dat_o => dat_o,
cyc_i => cyc_i,
ack_o => ack_o,
ack_oi => ack_oi,
we_i => we_i,
vmem_stb_i => vmem_stb_i,
reg_stb_i => reg_stb_i,
adr_i => adr_i,
s_data => s_data,
s_addr => s_addr,
s_oen => s_oen,
s_wrhn => s_wrhn,
s_wrln => s_wrln,
s_cen => s_cen,
h_sync => h_sync,
h_blank => h_blank,
v_sync => v_sync,
v_blank => v_blank,
h_tc => h_tc,
v_tc => v_tc,
blank => blank,
video_out => video_out,
 
T_v_we_o => T_v_we_o,
T_v_stb_o => T_v_stb_o,
T_v_ack_i => T_v_ack_i,
T_v_adr_o => T_v_adr_o,
T_v_sel_o => T_v_sel_o,
T_v_dat_o => T_v_dat_o,
T_v_dat_i => T_v_dat_i
);
end vga_chip;
/tags/a01/sync_gen.vhd
0,0 → 1,80
--
-- Programmable sync generator.
--
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31
-- This code is distributed under the terms and conditions of the GNU General Public Lince.
--
 
-- Standard library.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
 
library work;
use work.technology.all;
 
entity sync_gen is
port (
clk: in std_logic;
clk_en: in std_logic;
reset: in std_logic := '0';
 
bs: in std_logic_vector(7 downto 0);
ss: in std_logic_vector(7 downto 0);
se: in std_logic_vector(7 downto 0);
total: in std_logic_vector(7 downto 0);
 
sync: out std_logic;
blank: out std_logic;
tc: out std_logic;
count: out std_logic_vector (7 downto 0)
);
end sync_gen;
 
architecture sync_gen of sync_gen is
begin
-- And the sequential machine generating the output signals.
generator: process is
variable state: std_logic_vector(7 downto 0);
begin
wait until clk'event and clk='1';
if (reset = '1') then
tc <= '0';
state := (others => '0');
sync <= '0';
tc <= '0';
blank <= '1';
else
if (clk_en='1') then
if (state = bs) then
sync <= '0';
blank <= '1';
tc <= '0';
state := add_one(state);
elsif (state = ss) then
sync <= '1';
blank <= '1';
tc <= '1';
state := add_one(state);
elsif (state = se) then
sync <= '0';
blank <= '1';
tc <= '0';
state := add_one(state);
elsif (state = total) then
sync <= '0';
blank <= '0';
tc <= '0';
state := (others => '0');
else
tc <= '0';
state := add_one(state);
end if;
count <= state;
else
tc <= '0';
end if;
end if;
end process;
end sync_gen;
/tags/a01/vga_core.vhd
0,0 → 1,774
--
-- File: vga_core.vhd
--
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31
-- This code is distributed under the terms and conditions of the GNU General Public Lince.
--
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library work;
--use wb_tk.all;
use work.wb_tk.all;
 
entity vga_core is
generic (
-- cannot be overwritten at the moment...
v_mem_width: positive := 16;
fifo_size: positive := 256;
v_addr_width : positive := 20;
bus_width: positive := 8
);
port (
clk_i: in std_logic;
clk_en: in std_logic := '1';
rst_i: in std_logic := '0';
 
-- CPU bus interface
dat_i: in std_logic_vector (bus_width-1 downto 0);
dat_oi: in std_logic_vector (bus_width-1 downto 0);
dat_o: out std_logic_vector (bus_width-1 downto 0);
cyc_i: in std_logic;
ack_o: out std_logic;
ack_oi: in std_logic;
we_i: in std_logic;
vmem_stb_i: in std_logic;
reg_stb_i: in std_logic;
adr_i: in std_logic_vector (v_addr_width downto 0);
 
-- video memory SRAM interface
s_data : inout std_logic_vector((v_mem_width-1) downto 0);
s_addr : out std_logic_vector((v_addr_width-1) downto 0);
s_oen : out std_logic;
s_wrhn : out std_logic;
s_wrln : out std_logic;
s_cen : out std_logic;
 
-- sync blank and video signal outputs
h_sync: out std_logic;
h_blank: out std_logic;
v_sync: out std_logic;
v_blank: out std_logic;
h_tc: out std_logic;
v_tc: out std_logic;
blank: out std_logic;
video_out: out std_logic_vector (7 downto 0); -- video output binary signal (unused bits are forced to 0)
 
-- TEST SIGNALS
T_v_we_o: out std_logic;
T_v_stb_o: out std_logic;
T_v_ack_i: out std_logic;
T_v_adr_o : out std_logic_vector((v_addr_width-1) downto 0);
T_v_sel_o : out std_logic_vector((v_addr_width/8)-1 downto 0);
T_v_dat_o : out std_logic_vector((v_mem_width-1) downto 0);
T_v_dat_i : out std_logic_vector((v_mem_width-1) downto 0)
);
end vga_core;
 
architecture vga_core of vga_core is
component video_engine
generic (
v_mem_width: positive := 16;
v_addr_width: positive:= 20;
fifo_size: positive := 256;
dual_scan_fifo_size: positive := 256
);
port (
clk: in std_logic;
clk_en: in std_logic := '1';
reset: in std_logic := '0';
 
total: in std_logic_vector(v_addr_width-1 downto 0); -- total video memory size in bytes 7..0
fifo_treshold: in std_logic_vector(7 downto 0); -- priority change threshold
bpp: in std_logic_vector(1 downto 0); -- number of bits makes up a pixel valid values: 1,2,4,8
multi_scan: in std_logic_vector(1 downto 0); -- number of repeated scans
 
hbs: in std_logic_vector(7 downto 0);
hss: in std_logic_vector(7 downto 0);
hse: in std_logic_vector(7 downto 0);
htotal: in std_logic_vector(7 downto 0);
vbs: in std_logic_vector(7 downto 0);
vss: in std_logic_vector(7 downto 0);
vse: in std_logic_vector(7 downto 0);
vtotal: in std_logic_vector(7 downto 0);
 
pps: in std_logic_vector(7 downto 0);
 
high_prior: out std_logic; -- signals to the memory arbitrer to give high
-- priority to the video engine
v_mem_rd: out std_logic; -- video memory read request
v_mem_rdy: in std_logic; -- video memory data ready
v_mem_addr: out std_logic_vector (v_addr_width-1 downto 0); -- video memory address
v_mem_data: in std_logic_vector (v_mem_width-1 downto 0); -- video memory data
 
h_sync: out std_logic;
h_blank: out std_logic;
v_sync: out std_logic;
v_blank: out std_logic;
h_tc: out std_logic;
v_tc: out std_logic;
blank: out std_logic;
video_out: out std_logic_vector (7 downto 0) -- video output binary signal (unused bits are forced to 0)
);
end component video_engine;
 
component wb_async_slave
generic (
width: positive := 16;
addr_width: positive := 20
);
port (
clk_i: in std_logic;
rst_i: in std_logic := '0';
-- interface for wait-state generator state-machine
wait_state: in std_logic_vector (3 downto 0);
 
-- interface to wishbone master device
adr_i: in std_logic_vector (addr_width-1 downto 0);
sel_i: in std_logic_vector ((addr_width/8)-1 downto 0);
dat_i: in std_logic_vector (width-1 downto 0);
dat_o: out std_logic_vector (width-1 downto 0);
dat_oi: in std_logic_vector (width-1 downto 0) := (others => '-');
we_i: in std_logic;
stb_i: in std_logic;
ack_o: out std_logic := '0';
ack_oi: in std_logic := '-';
-- interface to async slave
a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z');
a_addr: out std_logic_vector (addr_width-1 downto 0) := (others => 'U');
a_rdn: out std_logic := '1';
a_wrn: out std_logic := '1';
a_cen: out std_logic := '1';
-- byte-enable signals
a_byen: out std_logic_vector ((addr_width/8)-1 downto 0)
);
end component;
 
component wb_arbiter
port (
-- clk: in std_logic;
rst_i: in std_logic := '0';
-- interface to master device a
a_we_i: in std_logic;
a_stb_i: in std_logic;
a_cyc_i: in std_logic;
a_ack_o: out std_logic;
a_ack_oi: in std_logic := '-';
a_err_o: out std_logic;
a_err_oi: in std_logic := '-';
a_rty_o: out std_logic;
a_rty_oi: in std_logic := '-';
-- interface to master device b
b_we_i: in std_logic;
b_stb_i: in std_logic;
b_cyc_i: in std_logic;
b_ack_o: out std_logic;
b_ack_oi: in std_logic := '-';
b_err_o: out std_logic;
b_err_oi: in std_logic := '-';
b_rty_o: out std_logic;
b_rty_oi: in std_logic := '-';
 
-- interface to shared devices
s_we_o: out std_logic;
s_stb_o: out std_logic;
s_cyc_o: out std_logic;
s_ack_i: in std_logic;
s_err_i: in std_logic := '-';
s_rty_i: in std_logic := '-';
mux_signal: out std_logic; -- 0: select A signals, 1: select B signals
 
-- misc control lines
priority: in std_logic -- 0: A have priority over B, 1: B have priority over A
);
end component;
 
component wb_out_reg
generic (
width : positive := 8;
bus_width: positive := 8;
offset: integer := 0
);
port (
clk_i: in std_logic;
rst_i: in std_logic;
rst_val: std_logic_vector(width-1 downto 0) := (others => '0');
 
dat_i: in std_logic_vector (bus_width-1 downto 0);
dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-');
dat_o: out std_logic_vector (bus_width-1 downto 0);
q: out std_logic_vector (width-1 downto 0);
we_i: in std_logic;
stb_i: in std_logic;
ack_o: out std_logic;
ack_oi: in std_logic := '-'
);
end component;
 
component wb_bus_upsize
generic (
m_bus_width: positive := 8; -- master bus width
m_addr_width: positive := 21; -- master bus width
s_bus_width: positive := 16; -- slave bus width
little_endien: boolean := true -- if set to false, big endien
);
port (
-- clk_i: in std_logic;
-- rst_i: in std_logic := '0';
 
-- Master bus interface
m_adr_i: in std_logic_vector (m_addr_width-1 downto 0);
m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1');
m_dat_i: in std_logic_vector (m_bus_width-1 downto 0);
m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-');
m_dat_o: out std_logic_vector (m_bus_width-1 downto 0);
m_cyc_i: in std_logic;
m_ack_o: out std_logic;
m_ack_oi: in std_logic := '-';
m_err_o: out std_logic;
m_err_oi: in std_logic := '-';
m_rty_o: out std_logic;
m_rty_oi: in std_logic := '-';
m_we_i: in std_logic;
m_stb_i: in std_logic;
 
-- Slave bus interface
s_adr_o: out std_logic_vector (m_addr_width-2 downto 0);
s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0);
s_dat_i: in std_logic_vector (s_bus_width-1 downto 0);
s_dat_o: out std_logic_vector (s_bus_width-1 downto 0);
s_cyc_o: out std_logic;
s_ack_i: in std_logic;
s_err_i: in std_logic := '-';
s_rty_i: in std_logic := '-';
s_we_o: out std_logic;
s_stb_o: out std_logic
);
end component;
 
signal reset_core: std_logic_vector(0 downto 0);
signal total: std_logic_vector(v_addr_width-1 downto 0);
signal fifo_treshold: std_logic_vector(7 downto 0);
signal bpp: std_logic_vector(1 downto 0);
signal multi_scan: std_logic_vector(1 downto 0);
signal hbs: std_logic_vector(7 downto 0);
signal hss: std_logic_vector(7 downto 0);
signal hse: std_logic_vector(7 downto 0);
signal htotal: std_logic_vector(7 downto 0);
signal vbs: std_logic_vector(7 downto 0);
signal vss: std_logic_vector(7 downto 0);
signal vse: std_logic_vector(7 downto 0);
signal vtotal: std_logic_vector(7 downto 0);
signal pps: std_logic_vector(7 downto 0);
signal wait_state: std_logic_vector (3 downto 0);
signal sync_pol: std_logic_vector (3 downto 0);
 
signal reset_core_do: std_logic_vector(bus_width-1 downto 0);
signal total0_do: std_logic_vector(bus_width-1 downto 0);
signal total1_do: std_logic_vector(bus_width-1 downto 0);
signal total2_do: std_logic_vector(bus_width-1 downto 0);
signal fifo_treshold_do: std_logic_vector(bus_width-1 downto 0);
signal bpp_do: std_logic_vector(bus_width-1 downto 0);
signal multi_scan_do: std_logic_vector(bus_width-1 downto 0);
signal hbs_do: std_logic_vector(bus_width-1 downto 0);
signal hss_do: std_logic_vector(bus_width-1 downto 0);
signal hse_do: std_logic_vector(bus_width-1 downto 0);
signal htotal_do: std_logic_vector(bus_width-1 downto 0);
signal vbs_do: std_logic_vector(bus_width-1 downto 0);
signal vss_do: std_logic_vector(bus_width-1 downto 0);
signal vse_do: std_logic_vector(bus_width-1 downto 0);
signal vtotal_do: std_logic_vector(bus_width-1 downto 0);
signal pps_do: std_logic_vector(bus_width-1 downto 0);
signal wait_state_do: std_logic_vector(bus_width-1 downto 0);
signal vm_do: std_logic_vector(bus_width-1 downto 0);
 
signal reset_core_sel: std_logic;
signal total0_sel: std_logic;
signal total1_sel: std_logic;
signal total2_sel: std_logic;
signal fifo_treshold_sel: std_logic;
signal bpp_sel: std_logic;
signal multi_scan_sel: std_logic;
signal hbs_sel: std_logic;
signal hss_sel: std_logic;
signal hse_sel: std_logic;
signal htotal_sel: std_logic;
signal vbs_sel: std_logic;
signal vss_sel: std_logic;
signal vse_sel: std_logic;
signal vtotal_sel: std_logic;
signal pps_sel: std_logic;
signal wait_state_sel: std_logic;
signal sync_pol_sel: std_logic;
 
signal reset_core_ack: std_logic;
signal total0_ack: std_logic;
signal total1_ack: std_logic;
signal total2_ack: std_logic;
signal fifo_treshold_ack: std_logic;
signal bpp_ack: std_logic;
signal multi_scan_ack: std_logic;
signal hbs_ack: std_logic;
signal hss_ack: std_logic;
signal hse_ack: std_logic;
signal htotal_ack: std_logic;
signal vbs_ack: std_logic;
signal vss_ack: std_logic;
signal vse_ack: std_logic;
signal vtotal_ack: std_logic;
signal pps_ack: std_logic;
signal wait_state_ack: std_logic;
signal vm_ack: std_logic;
 
signal a_adr_o : std_logic_vector((v_addr_width-1) downto 0);
signal a_sel_o : std_logic_vector((v_addr_width/8)-1 downto 0);
signal a_dat_o : std_logic_vector((v_mem_width-1) downto 0);
signal a_dat_i : std_logic_vector((v_mem_width-1) downto 0);
signal a_we_o : std_logic;
signal a_stb_o : std_logic;
signal a_cyc_o : std_logic;
signal a_ack_i : std_logic;
 
signal b_adr_o : std_logic_vector((v_addr_width-1) downto 0);
signal b_sel_o : std_logic_vector((v_addr_width/8)-1 downto 0);
-- signal b_dat_o : std_logic_vector((v_mem_width-1) downto 0);
signal b_dat_i : std_logic_vector((v_mem_width-1) downto 0);
signal b_stb_o : std_logic;
-- signal b_we_o : std_logic;
-- signal b_cyc_o : std_logic;
signal b_ack_i : std_logic;
 
signal v_we_o: std_logic;
signal v_stb_o: std_logic;
signal v_ack_i: std_logic;
signal v_adr_o : std_logic_vector((v_addr_width-1) downto 0);
signal v_sel_o : std_logic_vector((v_addr_width/8)-1 downto 0);
signal v_dat_o : std_logic_vector((v_mem_width-1) downto 0);
signal v_dat_i : std_logic_vector((v_mem_width-1) downto 0);
signal s_byen : std_logic_vector((v_addr_width/8)-1 downto 0);
 
signal mux_signal: std_logic;
 
signal high_prior: std_logic;
 
signal reset_engine: std_logic;
 
signal i_h_sync: std_logic;
signal i_h_blank: std_logic;
signal i_v_sync: std_logic;
signal i_v_blank: std_logic;
 
signal s_wrn : std_logic;
 
begin
-- map all registers:
reset_core_reg: wb_out_reg
generic map( width => 1, bus_width => bus_width , offset => 4 )
port map(
stb_i => reset_core_sel,
q => reset_core,
rst_val => "1",
dat_oi => vm_do,
dat_o => reset_core_do,
ack_oi => vm_ack,
ack_o => reset_core_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
total0_reg: wb_out_reg
generic map( width => 8, bus_width => bus_width , offset => 0 )
port map(
stb_i => total0_sel,
q => total(7 downto 0),
rst_val => "00000000",
dat_oi => reset_core_do,
dat_o => total0_do,
ack_oi => reset_core_ack,
ack_o => total0_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
total1_reg: wb_out_reg
generic map( width => 8, bus_width => bus_width , offset => 0 )
port map(
stb_i => total1_sel,
q => total(15 downto 8),
rst_val => "00000000",
dat_oi => total0_do,
dat_o => total1_do,
ack_oi => total0_ack,
ack_o => total1_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
total2_reg: wb_out_reg
generic map( width => 4, bus_width => bus_width , offset => 0 )
port map(
stb_i => total2_sel,
q => total(19 downto 16),
rst_val => "0000",
dat_oi => total1_do,
dat_o => total2_do,
ack_oi => total1_ack,
ack_o => total2_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
fifo_treshold_reg: wb_out_reg
generic map( width => 8, bus_width => bus_width , offset => 0 )
port map(
stb_i => fifo_treshold_sel,
q => fifo_treshold,
rst_val => "00000000",
dat_oi => total2_do,
dat_o => fifo_treshold_do,
ack_oi => total2_ack,
ack_o => fifo_treshold_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
bpp_reg: wb_out_reg
generic map( width => 2, bus_width => bus_width , offset => 0 )
port map(
stb_i => bpp_sel,
q => bpp,
rst_val => "00",
dat_oi => fifo_treshold_do,
dat_o => bpp_do,
ack_oi => fifo_treshold_ack,
ack_o => bpp_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
multi_scan_reg: wb_out_reg
generic map( width => 2, bus_width => bus_width , offset => 2 )
port map(
stb_i => multi_scan_sel,
q => multi_scan,
rst_val => "00",
dat_oi => bpp_do,
dat_o => multi_scan_do,
ack_oi => bpp_ack,
ack_o => multi_scan_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
hbs_reg: wb_out_reg
generic map( width => 8, bus_width => bus_width , offset => 0 )
port map(
stb_i => hbs_sel,
q => hbs,
rst_val => "00000000",
dat_oi => multi_scan_do,
dat_o => hbs_do,
ack_oi => multi_scan_ack,
ack_o => hbs_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
hss_reg: wb_out_reg
generic map( width => 8, bus_width => bus_width , offset => 0 )
port map(
stb_i => hss_sel,
q => hss,
rst_val => "00000000",
dat_oi => hbs_do,
dat_o => hss_do,
ack_oi => hbs_ack,
ack_o => hss_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
hse_reg: wb_out_reg
generic map( width => 8, bus_width => bus_width , offset => 0 )
port map(
stb_i => hse_sel,
q => hse,
rst_val => "00000000",
dat_oi => hss_do,
dat_o => hse_do,
ack_oi => hss_ack,
ack_o => hse_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
htotal_reg: wb_out_reg
generic map( width => 8, bus_width => bus_width , offset => 0 )
port map(
stb_i => htotal_sel,
q => htotal,
rst_val => "00000000",
dat_oi => hse_do,
dat_o => htotal_do,
ack_oi => hse_ack,
ack_o => htotal_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
vbs_reg: wb_out_reg
generic map( width => 8, bus_width => bus_width , offset => 0 )
port map(
stb_i => vbs_sel,
q => vbs,
rst_val => "00000000",
dat_oi => htotal_do,
dat_o => vbs_do,
ack_oi => htotal_ack,
ack_o => vbs_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
vss_reg: wb_out_reg
generic map( width => 8, bus_width => bus_width , offset => 0 )
port map(
stb_i => vss_sel,
q => vss,
rst_val => "00000000",
dat_oi => vbs_do,
dat_o => vss_do,
ack_oi => vbs_ack,
ack_o => vss_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
vse_reg: wb_out_reg
generic map( width => 8, bus_width => bus_width , offset => 0 )
port map(
stb_i => vse_sel,
q => vse,
rst_val => "00000000",
dat_oi => vss_do,
dat_o => vse_do,
ack_oi => vss_ack,
ack_o => vse_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
vtotal_reg: wb_out_reg
generic map( width => 8, bus_width => bus_width , offset => 0 )
port map(
stb_i => vtotal_sel,
q => vtotal,
rst_val => "00000000",
dat_oi => vse_do,
dat_o => vtotal_do,
ack_oi => vse_ack,
ack_o => vtotal_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
pps_reg: wb_out_reg
generic map( width => 8, bus_width => bus_width , offset => 0 )
port map(
stb_i => pps_sel,
q => pps,
rst_val => "00000000",
dat_oi => vtotal_do,
dat_o => pps_do,
ack_oi => vtotal_ack,
ack_o => pps_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
wait_state_reg: wb_out_reg
generic map( width => 4, bus_width => bus_width , offset => 0 )
port map(
stb_i => wait_state_sel,
q => wait_state,
rst_val => "0000",
dat_oi => pps_do,
dat_o => wait_state_do,
ack_oi => pps_ack,
ack_o => wait_state_ack,
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
sync_pol_reg: wb_out_reg
generic map( width => 4, bus_width => bus_width , offset => 4 )
port map(
stb_i => sync_pol_sel,
q => sync_pol,
rst_val => "0000",
dat_oi => wait_state_do,
dat_o => dat_o, -- END OF THE CHAIN
ack_oi => wait_state_ack,
ack_o => ack_o, -- END OF THE CHAIN
we_i => we_i, clk_i => clk_i, rst_i => rst_i, dat_i => dat_i );
 
reset_engine <= rst_i or reset_core(0);
 
v_e: video_engine
generic map ( v_mem_width => v_mem_width, v_addr_width => v_addr_width, fifo_size => fifo_size, dual_scan_fifo_size => fifo_size )
port map (
clk => clk_i,
clk_en => clk_en,
reset => reset_engine,
total => total,
fifo_treshold => fifo_treshold,
bpp => bpp,
multi_scan => multi_scan,
hbs => hbs,
hss => hss,
hse => hse,
htotal => htotal,
vbs => vbs,
vss => vss,
vse => vse,
vtotal => vtotal,
pps => pps,
 
high_prior => high_prior,
 
v_mem_rd => b_stb_o,
v_mem_rdy => b_ack_i,
v_mem_addr => b_adr_o,
v_mem_data => b_dat_i,
 
h_sync => i_h_sync,
h_blank => i_h_blank,
v_sync => i_v_sync,
v_blank => i_v_blank,
h_tc => h_tc,
v_tc => v_tc,
blank => blank,
video_out => video_out
);
 
h_sync <= i_h_sync xor sync_pol(0);
v_sync <= i_v_sync xor sync_pol(1);
h_blank <= i_h_blank;-- xor sync_pol(2);
v_blank <= i_v_blank;-- xor sync_pol(3);
 
resize: wb_bus_upsize
generic map (
m_bus_width => bus_width, s_bus_width => v_mem_width, m_addr_width => v_addr_width+1
)
port map (
m_adr_i => adr_i,
-- m_sel_i => (others => '1'),
m_dat_i => dat_i,
m_dat_oi => dat_oi, -- Beginning of the chain
m_cyc_i => cyc_i,
m_dat_o => vm_do,
m_ack_o => vm_ack,
m_ack_oi => ack_oi, -- Beginning of the chain
m_we_i => we_i,
m_stb_i => vmem_stb_i,
s_adr_o => a_adr_o,
s_sel_o => a_sel_o,
s_dat_i => a_dat_i,
s_dat_o => a_dat_o,
s_cyc_o => a_cyc_o,
s_ack_i => a_ack_i,
s_we_o => a_we_o,
s_stb_o => a_stb_o
);
 
 
arbiter: wb_arbiter
port map (
rst_i => reset_engine,
 
a_we_i => a_we_o,
a_cyc_i => a_cyc_o,
a_stb_i => a_stb_o,
a_ack_o => a_ack_i,
a_ack_oi => '-',
 
b_we_i => '0',
b_cyc_i => b_stb_o,
b_stb_i => b_stb_o,
b_ack_o => b_ack_i,
b_ack_oi => '0', -- maybe not needed at all
 
s_we_o => v_we_o,
s_stb_o => v_stb_o,
s_ack_i => v_ack_i,
 
mux_signal => mux_signal,
priority => high_prior
);
 
b_sel_o <= (others => '1');
bus_mux: process is
begin
wait on mux_signal, v_dat_i, a_adr_o, a_dat_o, b_adr_o, a_sel_o, b_sel_o;
if (mux_signal = '0') then
v_adr_o <= a_adr_o;
v_sel_o <= a_sel_o;
v_dat_o <= a_dat_o;
a_dat_i <= v_dat_i;
b_dat_i <= (others => '-');
else
v_adr_o <= b_adr_o;
v_sel_o <= b_sel_o;
v_dat_o <= (others => '-');
b_dat_i <= v_dat_i;
a_dat_i <= (others => '-');
end if;
end process;
 
mem_driver: wb_async_slave
generic map (width => v_mem_width, addr_width => v_addr_width)
port map (
clk_i => clk_i,
rst_i => reset_engine,
 
wait_state => wait_state,
adr_i => v_adr_o,
sel_i => v_sel_o,
dat_o => v_dat_i,
dat_i => v_dat_o,
-- dat_oi => (others => '0'), -- may not be needed
we_i => v_we_o,
stb_i => v_stb_o,
ack_o => v_ack_i,
ack_oi => '0', -- may not be needed
 
a_data => s_data,
a_addr => s_addr,
a_rdn => s_oen,
a_wrn => s_wrn,
a_cen => s_cen,
a_byen => s_byen
);
 
s_wrln <= s_wrn or s_byen(0);
s_wrhn <= s_wrn or s_byen(1);
 
addr_decoder: process is
begin
wait on reg_stb_i, adr_i;
 
reset_core_sel <= '0';
total0_sel <= '0';
total1_sel <= '0';
total2_sel <= '0';
fifo_treshold_sel <= '0';
bpp_sel <= '0';
multi_scan_sel <= '0';
hbs_sel <= '0';
hss_sel <= '0';
hse_sel <= '0';
htotal_sel <= '0';
vbs_sel <= '0';
vss_sel <= '0';
vse_sel <= '0';
vtotal_sel <= '0';
pps_sel <= '0';
wait_state_sel <= '0';
sync_pol_sel <= '0';
 
if (reg_stb_i = '1') then
case (adr_i(4 downto 0)) is
when "00000" => total0_sel <= '1';
when "00001" => total1_sel <= '1';
when "00010" => total2_sel <= '1';
when "00011" => fifo_treshold_sel <= '1';
 
when "00100" => hbs_sel <= '1';
when "00101" => hss_sel <= '1';
when "00110" => hse_sel <= '1';
when "00111" => htotal_sel <= '1';
 
when "01000" => vbs_sel <= '1';
when "01001" => vss_sel <= '1';
when "01010" => vse_sel <= '1';
when "01011" => vtotal_sel <= '1';
 
when "01100" => pps_sel <= '1';
when "01101" => wait_state_sel <= '1'; sync_pol_sel <= '1';
when "01110" => bpp_sel <= '1'; multi_scan_sel <= '1'; reset_core_sel <= '1';
when others =>
end case;
end if;
end process;
 
-- TEST SIGNALS
T_v_we_o <= v_we_o;
T_v_stb_o <= v_stb_o;
T_v_ack_i <= v_ack_i;
T_v_adr_o <= v_adr_o;
T_v_sel_o <= v_sel_o;
T_v_dat_o <= v_dat_o;
T_v_dat_i <= v_dat_i;
end vga_core;
 
/tags/a01/wb_tk.vhd
0,0 → 1,914
--
-- Wishbone bus toolkit.
--
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31
-- This code is distributed under the terms and conditions of the GNU General Public Lince.
--
--
-- ELEMENTS:
-- wb_bus_upsize: bus upsizer. Currently only 8->16 bit bus resize is supported
-- wb_async_slave: Wishbone bus to async (SRAM-like) bus slave bridge.
-- wb_arbiter: two-way bus arbiter. Asyncronous logic ensures 0-ws operation on shared bus
-- wb_out_reg: Wishbone bus compatible output register.
 
library IEEE;
use IEEE.std_logic_1164.all;
 
package wb_tk is
component wb_bus_upsize is
generic (
m_bus_width: positive := 8; -- master bus width
m_addr_width: positive := 21; -- master bus width
s_bus_width: positive := 16; -- slave bus width
s_addr_width: positive := 20; -- master bus width
little_endien: boolean := true -- if set to false, big endien
);
port (
-- clk_i: in std_logic;
-- rst_i: in std_logic := '0';
-- Master bus interface
m_adr_i: in std_logic_vector (m_addr_width-1 downto 0);
m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1');
m_dat_i: in std_logic_vector (m_bus_width-1 downto 0);
m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-');
m_dat_o: out std_logic_vector (m_bus_width-1 downto 0);
m_cyc_i: in std_logic;
m_ack_o: out std_logic;
m_ack_oi: in std_logic := '-';
m_err_o: out std_logic;
m_err_oi: in std_logic := '-';
m_rty_o: out std_logic;
m_rty_oi: in std_logic := '-';
m_we_i: in std_logic;
m_stb_i: in std_logic;
-- Slave bus interface
s_adr_o: out std_logic_vector (s_addr_width-1 downto 0);
s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0);
s_dat_i: in std_logic_vector (s_bus_width-1 downto 0);
s_dat_o: out std_logic_vector (s_bus_width-1 downto 0);
s_cyc_o: out std_logic;
s_ack_i: in std_logic;
s_err_i: in std_logic := '-';
s_rty_i: in std_logic := '-';
s_we_o: out std_logic;
s_stb_o: out std_logic
);
end component;
component wb_async_master is
generic (
width: positive := 16;
addr_width: positive := 20
);
port (
clk_i: in std_logic;
rst_i: in std_logic := '0';
-- interface to wb slave devices
s_adr_o: out std_logic_vector (addr_width-1 downto 0);
s_sel_o: out std_logic_vector ((width/8)-1 downto 0);
s_dat_i: in std_logic_vector (width-1 downto 0);
s_dat_o: out std_logic_vector (width-1 downto 0);
s_cyc_o: out std_logic;
s_ack_i: in std_logic;
s_err_i: in std_logic := '-';
s_rty_i: in std_logic := '-';
s_we_o: out std_logic;
s_stb_o: out std_logic;
 
-- interface to asyncron master device
a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z');
a_addr: in std_logic_vector (addr_width-1 downto 0) := (others => 'U');
a_rdn: in std_logic := '1';
a_wrn: in std_logic := '1';
a_cen: in std_logic := '1';
a_byen: in std_logic_vector ((width/8)-1 downto 0);
a_waitn: out std_logic
);
end component;
component wb_async_slave is
generic (
width: positive := 16;
addr_width: positive := 20
);
port (
clk_i: in std_logic;
rst_i: in std_logic := '0';
-- interface for wait-state generator state-machine
wait_state: in std_logic_vector (3 downto 0);
-- interface to wishbone master device
adr_i: in std_logic_vector (addr_width-1 downto 0);
sel_i: in std_logic_vector ((addr_width/8)-1 downto 0);
dat_i: in std_logic_vector (width-1 downto 0);
dat_o: out std_logic_vector (width-1 downto 0);
dat_oi: in std_logic_vector (width-1 downto 0) := (others => '-');
we_i: in std_logic;
stb_i: in std_logic;
ack_o: out std_logic := '0';
ack_oi: in std_logic := '-';
-- interface to async slave
a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z');
a_addr: out std_logic_vector (addr_width-1 downto 0) := (others => 'U');
a_rdn: out std_logic := '1';
a_wrn: out std_logic := '1';
a_cen: out std_logic := '1';
-- byte-enable signals
a_byen: out std_logic_vector ((width/8)-1 downto 0)
);
end component;
component wb_arbiter is
port (
-- clk_i: in std_logic;
rst_i: in std_logic := '0';
-- interface to master device a
a_we_i: in std_logic;
a_stb_i: in std_logic;
a_cyc_i: in std_logic;
a_ack_o: out std_logic;
a_ack_oi: in std_logic := '-';
a_err_o: out std_logic;
a_err_oi: in std_logic := '-';
a_rty_o: out std_logic;
a_rty_oi: in std_logic := '-';
-- interface to master device b
b_we_i: in std_logic;
b_stb_i: in std_logic;
b_cyc_i: in std_logic;
b_ack_o: out std_logic;
b_ack_oi: in std_logic := '-';
b_err_o: out std_logic;
b_err_oi: in std_logic := '-';
b_rty_o: out std_logic;
b_rty_oi: in std_logic := '-';
-- interface to shared devices
s_we_o: out std_logic;
s_stb_o: out std_logic;
s_cyc_o: out std_logic;
s_ack_i: in std_logic;
s_err_i: in std_logic := '-';
s_rty_i: in std_logic := '-';
mux_signal: out std_logic; -- 0: select A signals, 1: select B signals
-- misc control lines
priority: in std_logic -- 0: A have priority over B, 1: B have priority over A
);
end component;
component wb_out_reg is
generic (
width : positive := 8;
bus_width: positive := 8;
offset: integer := 0
);
port (
clk_i: in std_logic;
rst_i: in std_logic;
rst_val: std_logic_vector(width-1 downto 0) := (others => '0');
dat_i: in std_logic_vector (bus_width-1 downto 0);
dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-');
dat_o: out std_logic_vector (bus_width-1 downto 0);
q: out std_logic_vector (width-1 downto 0);
we_i: in std_logic;
stb_i: in std_logic;
ack_o: out std_logic;
ack_oi: in std_logic := '-'
);
end component;
end wb_tk;
 
-------------------------------------------------------------------------------
--
-- wb_bus_upsize
--
-------------------------------------------------------------------------------
 
library IEEE;
library synopsys;
use IEEE.std_logic_1164.all;
use synopsys.std_logic_arith.all;
 
library work;
use work.technology.all;
 
entity wb_bus_upsize is
generic (
m_bus_width: positive := 8; -- master bus width
m_addr_width: positive := 21; -- master bus width
s_bus_width: positive := 16; -- slave bus width
s_addr_width: positive := 20; -- master bus width
little_endien: boolean := true -- if set to false, big endien
);
port (
-- clk_i: in std_logic;
-- rst_i: in std_logic := '0';
 
-- Master bus interface
m_adr_i: in std_logic_vector (m_addr_width-1 downto 0);
m_sel_i: in std_logic_vector ((m_bus_width/8)-1 downto 0) := (others => '1');
m_dat_i: in std_logic_vector (m_bus_width-1 downto 0);
m_dat_oi: in std_logic_vector (m_bus_width-1 downto 0) := (others => '-');
m_dat_o: out std_logic_vector (m_bus_width-1 downto 0);
m_cyc_i: in std_logic;
m_ack_o: out std_logic;
m_ack_oi: in std_logic := '-';
m_err_o: out std_logic;
m_err_oi: in std_logic := '-';
m_rty_o: out std_logic;
m_rty_oi: in std_logic := '-';
m_we_i: in std_logic;
m_stb_i: in std_logic;
 
-- Slave bus interface
s_adr_o: out std_logic_vector (s_addr_width-1 downto 0);
s_sel_o: out std_logic_vector ((s_bus_width/8)-1 downto 0);
s_dat_i: in std_logic_vector (s_bus_width-1 downto 0);
s_dat_o: out std_logic_vector (s_bus_width-1 downto 0);
s_cyc_o: out std_logic;
s_ack_i: in std_logic;
s_err_i: in std_logic := '-';
s_rty_i: in std_logic := '-';
s_we_o: out std_logic;
s_stb_o: out std_logic
);
end wb_bus_upsize;
 
architecture wb_bus_upsize of wb_bus_upsize is
function log2(inp : integer) return integer is
begin
if (inp < 1) then return 0; end if;
if (inp < 2) then return 0; end if;
if (inp < 4) then return 1; end if;
if (inp < 8) then return 2; end if;
if (inp < 16) then return 3; end if;
if (inp < 32) then return 4; end if;
if (inp < 64) then return 5; end if;
if (inp < 128) then return 6; end if;
if (inp < 256) then return 7; end if;
if (inp < 512) then return 8; end if;
if (inp < 1024) then return 9; end if;
if (inp < 2048) then return 10; end if;
if (inp < 4096) then return 11; end if;
if (inp < 8192) then return 12; end if;
if (inp < 16384) then return 13; end if;
if (inp < 32768) then return 14; end if;
if (inp < 65538) then return 15; end if;
return 16;
end;
function equ(a : std_logic_vector; b : integer) return boolean is
variable b_s : std_logic_vector(a'RANGE);
begin
b_s := CONV_STD_LOGIC_VECTOR(b,a'HIGH+1);
return (a = b_s);
end;
constant addr_diff: integer := log2(s_bus_width/m_bus_width);
signal i_m_dat_o: std_logic_vector(m_bus_width-1 downto 0);
begin
assert (m_addr_width = s_addr_width+addr_diff) report "Address widths are not consistent" severity FAILURE;
s_adr_o <= m_adr_i(m_addr_width-addr_diff downto addr_diff);
s_we_o <= m_we_i;
m_ack_o <= (m_stb_i and s_ack_i) or (not m_stb_i and m_ack_oi);
m_err_o <= (m_stb_i and s_err_i) or (not m_stb_i and m_err_oi);
m_rty_o <= (m_stb_i and s_rty_i) or (not m_stb_i and m_rty_oi);
s_stb_o <= m_stb_i;
s_cyc_o <= m_cyc_i;
 
sel_dat_mux: process is
begin
wait on s_dat_i, m_adr_i;
if (little_endien) then
for i in s_sel_o'RANGE loop
if (equ(m_adr_i(addr_diff-1 downto 0),i)) then
s_sel_o(i) <= '1';
i_m_dat_o <= s_dat_i(8*i+7 downto 8*i+0);
else
s_sel_o(i) <= '0';
end if;
end loop;
else
for i in s_sel_o'RANGE loop
if (equ(m_adr_i(addr_diff-1 downto 0),i)) then
s_sel_o(s_sel_o'HIGH-i) <= '1';
i_m_dat_o <= s_dat_i(s_dat_i'HIGH-8*i downto s_dat_i'HIGH-8*i-7);
else
s_sel_o(s_sel_o'HIGH-i) <= '0';
end if;
end loop;
end if;
end process;
 
d_i_for: for i in m_dat_o'RANGE generate
m_dat_o(i) <= (m_stb_i and i_m_dat_o(i)) or (not m_stb_i and m_dat_oi(i));
end generate;
 
d_o_for: for i in s_sel_o'RANGE generate
s_dat_o(8*i+7 downto 8*i+0) <= m_dat_i;
end generate;
end wb_bus_upsize;
 
-------------------------------------------------------------------------------
--
-- wb_async_master
--
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library work;
use work.technology.all;
 
entity wb_async_master is
generic (
width: positive := 16;
addr_width: positive := 20
);
port (
clk_i: in std_logic;
rst_i: in std_logic := '0';
-- interface to wb slave devices
s_adr_o: out std_logic_vector (addr_width-1 downto 0);
s_sel_o: out std_logic_vector ((width/8)-1 downto 0);
s_dat_i: in std_logic_vector (width-1 downto 0);
s_dat_o: out std_logic_vector (width-1 downto 0);
s_cyc_o: out std_logic;
s_ack_i: in std_logic;
s_err_i: in std_logic := '-';
s_rty_i: in std_logic := '-';
s_we_o: out std_logic;
s_stb_o: out std_logic;
 
-- interface to asyncron master device
a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z');
a_addr: in std_logic_vector (addr_width-1 downto 0) := (others => 'U');
a_rdn: in std_logic := '1';
a_wrn: in std_logic := '1';
a_cen: in std_logic := '1';
a_byen: in std_logic_vector ((width/8)-1 downto 0);
a_waitn: out std_logic
);
end wb_async_master;
 
architecture wb_async_master of wb_async_master is
component d_ff
port ( d : in STD_LOGIC;
clk: in STD_LOGIC;
ena: in STD_LOGIC := '1';
clr: in STD_LOGIC := '0';
pre: in STD_LOGIC := '0';
q : out STD_LOGIC
);
end component;
signal wg_clk, wg_pre, wg_q: std_logic;
signal i_cyc_o, i_stb_o, i_we_o: std_logic;
signal i_waitn: std_logic;
begin
ctrl: process is
begin
wait until clk_i'EVENT and clk_i = '1';
if (rst_i = '1') then
i_cyc_o <= '0';
i_stb_o <= '0';
i_we_o <= '0';
else
if (a_cen = '0') then
i_stb_o <= not (a_rdn and a_wrn);
i_we_o <= not a_wrn;
i_cyc_o <= '1';
else
i_cyc_o <= '0';
i_stb_o <= '0';
i_we_o <= '0';
end if;
end if;
end process;
s_cyc_o <= i_cyc_o and not i_waitn;
s_stb_o <= i_stb_o and not i_waitn;
s_we_o <= i_we_o and not i_waitn;
 
w_ff1: d_ff port map (
d => s_ack_i,
clk => clk_i,
ena => '1',
clr => rst_i,
pre => '0',
q => wg_q
);
wg_clk <= not a_cen;
wg_pre <= wg_q or rst_i;
w_ff2: d_ff port map (
d => '0',
clk => wg_clk,
ena => '1',
clr => '0',
pre => wg_pre,
q => i_waitn
);
a_waitn <= i_waitn;
 
s_adr_o <= a_addr;
negate: for i in s_sel_o'RANGE generate s_sel_o(i) <= not a_byen(i); end generate;
s_dat_o <= a_data;
 
a_data_out: process is
begin
wait on s_dat_i, a_rdn, a_cen;
if (a_rdn = '0' and a_cen = '0') then
a_data <= s_dat_i;
else
a_data <= (others => 'Z');
end if;
end process;
end wb_async_master;
 
-------------------------------------------------------------------------------
--
-- wb_async_slave
--
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library work;
use work.technology.all;
 
entity wb_async_slave is
generic (
width: positive := 16;
addr_width: positive := 20
);
port (
clk_i: in std_logic;
rst_i: in std_logic := '0';
-- interface for wait-state generator state-machine
wait_state: in std_logic_vector (3 downto 0);
 
-- interface to wishbone master device
adr_i: in std_logic_vector (addr_width-1 downto 0);
sel_i: in std_logic_vector ((addr_width/8)-1 downto 0);
dat_i: in std_logic_vector (width-1 downto 0);
dat_o: out std_logic_vector (width-1 downto 0);
dat_oi: in std_logic_vector (width-1 downto 0) := (others => '-');
we_i: in std_logic;
stb_i: in std_logic;
ack_o: out std_logic := '0';
ack_oi: in std_logic := '-';
-- interface to async slave
a_data: inout std_logic_vector (width-1 downto 0) := (others => 'Z');
a_addr: out std_logic_vector (addr_width-1 downto 0) := (others => 'U');
a_rdn: out std_logic := '1';
a_wrn: out std_logic := '1';
a_cen: out std_logic := '1';
-- byte-enable signals
a_byen: out std_logic_vector ((width/8)-1 downto 0)
);
end wb_async_slave;
 
architecture wb_async_slave of wb_async_slave is
-- multiplexed access signals to memory
signal i_ack: std_logic;
signal sm_ack: std_logic;
 
type states is (sm_idle, sm_wait, sm_deact);
signal state: states;
signal cnt: std_logic_vector(3 downto 0);
begin
ack_o <= (stb_i and i_ack) or (not stb_i and ack_oi);
dat_o_gen: for i in dat_o'RANGE generate
dat_o(i) <= (stb_i and a_data(i)) or (not stb_i and dat_oi(i));
end generate;
-- For 0WS operation i_ack is an async signal otherwise it's a sync one.
i_ack_gen: process is
begin
wait on sm_ack, stb_i, wait_state, state;
if (wait_state = "0000") then
case (state) is
when sm_deact => i_ack <= '0';
when others => i_ack <= stb_i;
end case;
else
i_ack <= sm_ack;
end if;
end process;
-- SRAM signal-handler process
sram_signals: process is
begin
wait on state,we_i,a_data,adr_i,rst_i, stb_i, sel_i, dat_i;
if (rst_i = '1') then
a_wrn <= '1';
a_rdn <= '1';
a_cen <= '1';
a_addr <= (others => '-');
a_data <= (others => 'Z');
a_byen <= (others => '1');
else
case (state) is
when sm_deact =>
a_wrn <= '1';
a_rdn <= '1';
a_cen <= '1';
a_addr <= (others => '-');
a_data <= (others => 'Z');
a_byen <= (others => '1');
when others =>
a_addr <= adr_i;
a_rdn <= not (not we_i and stb_i);
a_wrn <= not (we_i and stb_i);
a_cen <= not stb_i;
a_byen <= not sel_i;
if (we_i = '1') then
a_data <= dat_i;
else
a_data <= (others => 'Z');
end if;
end case;
end if;
end process;
 
-- Aysnc access state-machine.
async_sm: process is
-- variable cnt: std_logic_vector(3 downto 0) := "0000";
-- variable state: states := init;
begin
wait until clk_i'EVENT and clk_i = '1';
if (rst_i = '1') then
state <= sm_idle;
cnt <= ((0) => '1', others => '0');
sm_ack <= '0';
else
case (state) is
when sm_idle =>
-- Check if anyone needs access to the memory.
-- it's rdy signal will already be pulled low, so we only have to start the access
if (stb_i = '1') then
case wait_state is
when "0000" =>
sm_ack <= '1';
state <= sm_deact;
when "0001" =>
sm_ack <= '1';
cnt <= "0001";
state <= sm_wait;
when others =>
sm_ack <= '0';
cnt <= "0001";
state <= sm_wait;
end case;
end if;
when sm_wait =>
if (cnt = wait_state) then
-- wait cycle completed.
state <= sm_deact;
sm_ack <= '0';
cnt <= "0000";
else
if (add_one(cnt) = wait_state) then
sm_ack <= '1';
else
sm_ack <= '0';
end if;
cnt <= add_one(cnt);
end if;
when sm_deact =>
if (stb_i = '1') then
case wait_state is
when "0000" =>
cnt <= "0000";
sm_ack <= '0';
state <= sm_wait;
when others =>
sm_ack <= '0';
cnt <= "0000";
state <= sm_wait;
end case;
else
sm_ack <= '0';
state <= sm_idle;
end if;
end case;
end if;
end process;
end wb_async_slave;
 
-------------------------------------------------------------------------------
--
-- wb_arbiter
--
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library work;
use work.technology.all;
 
entity wb_arbiter is
port (
-- clk: in std_logic;
rst_i: in std_logic := '0';
-- interface to master device a
a_we_i: in std_logic;
a_stb_i: in std_logic;
a_cyc_i: in std_logic;
a_ack_o: out std_logic;
a_ack_oi: in std_logic := '-';
a_err_o: out std_logic;
a_err_oi: in std_logic := '-';
a_rty_o: out std_logic;
a_rty_oi: in std_logic := '-';
-- interface to master device b
b_we_i: in std_logic;
b_stb_i: in std_logic;
b_cyc_i: in std_logic;
b_ack_o: out std_logic;
b_ack_oi: in std_logic := '-';
b_err_o: out std_logic;
b_err_oi: in std_logic := '-';
b_rty_o: out std_logic;
b_rty_oi: in std_logic := '-';
 
-- interface to shared devices
s_we_o: out std_logic;
s_stb_o: out std_logic;
s_cyc_o: out std_logic;
s_ack_i: in std_logic;
s_err_i: in std_logic := '-';
s_rty_i: in std_logic := '-';
mux_signal: out std_logic; -- 0: select A signals, 1: select B signals
 
-- misc control lines
priority: in std_logic -- 0: A have priority over B, 1: B have priority over A
);
end wb_arbiter;
 
-- This acthitecture is a clean asyncron state-machine. However it cannot be mapped to FPGA architecture
architecture behaviour of wb_arbiter is
type states is (idle,aa,ba);
signal i_mux_signal: std_logic;
signal e_state: states;
begin
mux_signal <= i_mux_signal;
sm: process is
variable state: states;
begin
wait on a_cyc_i, b_cyc_i, priority, rst_i;
if (rst_i = '1') then
state := idle;
i_mux_signal <= priority;
else
case (state) is
when idle =>
if (a_cyc_i = '1' and (priority = '0' or b_cyc_i = '0')) then
state := aa;
i_mux_signal <= '0';
elsif (b_cyc_i = '1' and (priority = '1' or a_cyc_i = '0')) then
state := ba;
i_mux_signal <= '1';
else
i_mux_signal <= priority;
end if;
when aa =>
if (a_cyc_i = '0') then
if (b_cyc_i = '1') then
state := ba;
i_mux_signal <= '1';
else
state := idle;
i_mux_signal <= priority;
end if;
else
i_mux_signal <= '0';
end if;
when ba =>
if (b_cyc_i = '0') then
if (a_cyc_i = '1') then
state := aa;
i_mux_signal <= '0';
else
state := idle;
i_mux_signal <= priority;
end if;
else
i_mux_signal <= '1';
end if;
end case;
end if;
e_state <= state;
end process;
signal_mux: process is
begin
wait on a_we_i, a_stb_i, a_ack_oi, a_err_oi, a_rty_oi, a_cyc_i,
b_we_i, b_stb_i, b_ack_oi, b_err_oi, b_rty_oi, b_cyc_i,
s_ack_i, s_err_i, s_rty_i, i_mux_signal;
if (i_mux_signal = '0') then
s_we_o <= a_we_i;
s_stb_o <= a_stb_i;
s_cyc_o <= a_cyc_i;
a_ack_o <= (a_stb_i and s_ack_i) or (not a_stb_i and a_ack_oi);
a_err_o <= (a_stb_i and s_err_i) or (not a_stb_i and a_err_oi);
a_rty_o <= (a_stb_i and s_rty_i) or (not a_stb_i and a_rty_oi);
b_ack_o <= (b_stb_i and '0') or (not b_stb_i and b_ack_oi);
b_err_o <= (b_stb_i and '0') or (not b_stb_i and b_err_oi);
b_rty_o <= (b_stb_i and '0') or (not b_stb_i and b_rty_oi);
else
s_we_o <= b_we_i;
s_stb_o <= b_stb_i;
s_cyc_o <= b_cyc_i;
b_ack_o <= (b_stb_i and s_ack_i) or (not b_stb_i and b_ack_oi);
b_err_o <= (b_stb_i and s_err_i) or (not b_stb_i and b_err_oi);
b_rty_o <= (b_stb_i and s_rty_i) or (not b_stb_i and b_rty_oi);
a_ack_o <= (a_stb_i and '0') or (not a_stb_i and a_ack_oi);
a_err_o <= (a_stb_i and '0') or (not a_stb_i and a_err_oi);
a_rty_o <= (a_stb_i and '0') or (not a_stb_i and a_rty_oi);
end if;
end process;
end behaviour;
 
-- This acthitecture is a more-or-less structural implementation. Fits for FPGA realization.
architecture FPGA of wb_arbiter is
component d_ff
port ( d : in STD_LOGIC;
clk: in STD_LOGIC;
ena: in STD_LOGIC := '1';
clr: in STD_LOGIC := '0';
pre: in STD_LOGIC := '0';
q : out STD_LOGIC
);
end component;
signal i_mux_signal: std_logic;
type states is (idle,aa,ba,XX);
signal e_state: states;
 
-- signals for a DFF in FPGA
signal idle_s, aa_s, ba_s: std_logic;
signal aa_clk, aa_ena, aa_clr, aa_pre: std_logic;
signal ba_clk, ba_ena, ba_clr, ba_pre: std_logic;
 
begin
mux_signal <= i_mux_signal;
idle_s <= not (a_cyc_i or b_cyc_i);
aa_clr <= rst_i or not a_cyc_i;
aa_clk <= a_cyc_i;
aa_ena <= not b_cyc_i and priority;
aa_pre <= (a_cyc_i and not priority and not ba_s) or (a_cyc_i and not b_cyc_i);
aa_ff: d_ff port map (
d => '1',
clk => aa_clk,
ena => aa_ena,
clr => aa_clr,
pre => aa_pre,
q => aa_s
);
ba_clr <= rst_i or not b_cyc_i;
ba_clk <= b_cyc_i;
ba_ena <= not a_cyc_i and not priority;
ba_pre <= (b_cyc_i and priority and not aa_s) or (b_cyc_i and not a_cyc_i);
ba_ff: d_ff port map (
d => '1',
clk => ba_clk,
ena => ba_ena,
clr => ba_clr,
pre => ba_pre,
q => ba_s
);
i_mux_signal <= (priority and idle_s) or ba_s;
signal_mux: process is
begin
wait on a_we_i, a_stb_i, a_ack_oi, a_err_oi, a_rty_oi, a_cyc_i,
b_we_i, b_stb_i, b_ack_oi, b_err_oi, b_rty_oi, b_cyc_i,
s_ack_i, s_err_i, s_rty_i, i_mux_signal;
if (i_mux_signal = '0') then
s_we_o <= a_we_i;
s_stb_o <= a_stb_i;
s_cyc_o <= a_cyc_i;
a_ack_o <= (a_stb_i and s_ack_i) or (not a_stb_i and a_ack_oi);
a_err_o <= (a_stb_i and s_err_i) or (not a_stb_i and a_err_oi);
a_rty_o <= (a_stb_i and s_rty_i) or (not a_stb_i and a_rty_oi);
b_ack_o <= (b_stb_i and '0') or (not b_stb_i and b_ack_oi);
b_err_o <= (b_stb_i and '0') or (not b_stb_i and b_err_oi);
b_rty_o <= (b_stb_i and '0') or (not b_stb_i and b_rty_oi);
else
s_we_o <= b_we_i;
s_stb_o <= b_stb_i;
s_cyc_o <= b_cyc_i;
b_ack_o <= (b_stb_i and s_ack_i) or (not b_stb_i and b_ack_oi);
b_err_o <= (b_stb_i and s_err_i) or (not b_stb_i and b_err_oi);
b_rty_o <= (b_stb_i and s_rty_i) or (not b_stb_i and b_rty_oi);
a_ack_o <= (a_stb_i and '0') or (not a_stb_i and a_ack_oi);
a_err_o <= (a_stb_i and '0') or (not a_stb_i and a_err_oi);
a_rty_o <= (a_stb_i and '0') or (not a_stb_i and a_rty_oi);
end if;
end process;
gen_e_state: process is
begin
wait on idle_s,aa_s,ba_s;
if (idle_s = '1' and ba_s = '0' and aa_s = '0') then e_state <= idle;
elsif (idle_s = '0' and ba_s = '1' and aa_s = '0') then e_state <= aa;
elsif (idle_s = '0' and ba_s = '0' and aa_s = '1') then e_state <= ba;
else e_state <= XX;
end if;
end process;
end FPGA;
 
-------------------------------------------------------------------------------
--
-- wb_out_reg
--
-------------------------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library work;
use work.technology.all;
 
entity wb_out_reg is
generic (
width : positive := 8;
bus_width: positive := 8;
offset: integer := 0
);
port (
clk_i: in std_logic;
rst_i: in std_logic;
rst_val: std_logic_vector(width-1 downto 0) := (others => '0');
 
dat_i: in std_logic_vector (bus_width-1 downto 0);
dat_oi: in std_logic_vector (bus_width-1 downto 0) := (others => '-');
dat_o: out std_logic_vector (bus_width-1 downto 0);
q: out std_logic_vector (width-1 downto 0);
we_i: in std_logic;
stb_i: in std_logic;
ack_o: out std_logic;
ack_oi: in std_logic := '-'
);
end wb_out_reg;
 
architecture wb_out_reg of wb_out_reg is
signal content : std_logic_vector (width-1 downto 0);
begin
-- output bus handling with logic
gen_dat_o: process is
variable rd_sel: std_logic;
begin
wait on dat_oi, we_i, stb_i, content;
rd_sel := stb_i and not we_i;
for i in bus_width-1 downto 0 loop
if (i >= offset and i < offset+width) then
dat_o(i) <= (dat_oi(i) and not rd_sel) or (content(i-offset) and rd_sel);
else
dat_o(i) <= dat_oi(i);
end if;
end loop;
end process;
 
-- this item never generates any wait-states
ack_o <= stb_i or ack_oi;
reg: process is
begin
wait until clk_i'EVENT and clk_i='1';
if (rst_i = '1') then
content <= rst_val;
else
if (stb_i = '1' and we_i = '1') then
content <= dat_i(width+offset-1 downto offset);
end if;
end if;
end process;
q <= content;
end wb_out_reg;
/tags/a01/hv_sync.vhd
0,0 → 1,149
--
-- Horizontal and vertical sync generator.
--
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31
-- This code is distributed under the terms and conditions of the GNU General Public Lince.
--
 
library IEEE;
use IEEE.std_logic_1164.all;
 
entity hv_sync is
port (
clk: in std_logic;
pix_clk_en: in std_logic := '1';
reset: in std_logic := '0';
 
hbs: in std_logic_vector(7 downto 0);
hss: in std_logic_vector(7 downto 0);
hse: in std_logic_vector(7 downto 0);
htotal: in std_logic_vector(7 downto 0);
vbs: in std_logic_vector(7 downto 0);
vss: in std_logic_vector(7 downto 0);
vse: in std_logic_vector(7 downto 0);
vtotal: in std_logic_vector(7 downto 0);
 
h_sync: out std_logic;
h_blank: out std_logic;
v_sync: out std_logic;
v_blank: out std_logic;
h_tc: out std_logic;
v_tc: out std_logic;
blank: out std_logic
);
end hv_sync;
 
architecture hv_sync of hv_sync is
component sync_gen
port (
clk: in std_logic;
clk_en: in std_logic;
reset: in std_logic := '0';
bs: in std_logic_vector(7 downto 0);
ss: in std_logic_vector(7 downto 0);
se: in std_logic_vector(7 downto 0);
total: in std_logic_vector(7 downto 0);
sync: out std_logic;
blank: out std_logic;
tc: out std_logic;
count: out std_logic_vector (7 downto 0)
);
end component;
signal h_blank_i: std_logic;
signal v_blank_i: std_logic;
signal h_tc_i: std_logic;
signal hcen: std_logic;
signal vcen: std_logic;
 
constant h_pre_div_factor: integer := 3;
constant v_pre_div_factor: integer := 3;
subtype h_div_var is integer range 0 to h_pre_div_factor;
subtype v_div_var is integer range 0 to v_pre_div_factor;
 
begin
h_pre_div : process is
variable cntr: h_div_var;
begin
wait until clk'EVENT and clk='1';
if (reset = '1') then
cntr := 0;
hcen <= '0';
else
if (pix_clk_en='1') then
if (cntr = h_pre_div_factor) then
cntr := 0;
hcen <= '1';
else
cntr := cntr+1;
hcen <= '0';
end if;
else
hcen <= '0';
end if;
end if;
end process;
 
h_sync_gen : sync_gen
port map (
clk => clk,
clk_en => hcen,
reset => reset,
bs => hbs,
ss => hss,
se => hse,
total => htotal,
sync => h_sync,
blank => h_blank_i,
tc => h_tc_i
);
 
h_tc <= h_tc_i;
 
v_pre_div : process is
variable cntr: v_div_var;
begin
wait until clk'EVENT and clk='1';
if (reset = '1') then
cntr := 0;
vcen <= '0';
else
if (h_tc_i='1') then
if (cntr = v_pre_div_factor) then
cntr := 0;
vcen <= '1';
else
cntr := cntr+1;
vcen <= '0';
end if;
else
vcen <= '0';
end if;
end if;
end process;
 
v_sync_gen : sync_gen
port map (
clk => clk,
clk_en => vcen,
reset => reset,
bs => vbs,
ss => vss,
se => vse,
total => vtotal,
sync => v_sync,
blank => v_blank_i,
tc => v_tc
);
 
blank <= h_blank_i or v_blank_i;
h_blank <= h_blank_i;
v_blank <= v_blank_i;
end hv_sync;
/tags/a01/technology.vhd
0,0 → 1,194
--
-- Technology mapping library. ALTERA edition.
--
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31
-- This code is distributed under the terms and conditions of the GNU General Public Lince.
--
 
library IEEE;
use IEEE.std_logic_1164.all;
library exemplar;
use exemplar.exemplar_1164.all;
 
package technology is
function add_one(inp : std_logic_vector) return std_logic_vector;
function is_zero(inp : std_logic_vector) return boolean;
function sl(l: std_logic_vector; r: integer) return std_logic_vector;
-- procedure inc(data : inout std_logic_vector);
function "+"(op_l, op_r: std_logic_vector) return std_logic_vector;
 
component d_ff is
port ( d : in STD_LOGIC;
clk: in STD_LOGIC;
ena: in STD_LOGIC := '1';
clr: in STD_LOGIC := '0';
pre: in STD_LOGIC := '0';
q : out STD_LOGIC
);
end component;
component fifo is
generic (fifo_width : positive;
used_width : positive;
fifo_depth : positive
);
port (d_in : in std_logic_vector(fifo_width-1 downto 0);
clk : in std_logic;
wr : in std_logic;
rd : in std_logic;
a_clr : in std_logic := '0';
s_clr : in std_logic := '0';
d_out : out std_logic_vector(fifo_width-1 downto 0);
used : out std_logic_vector(used_width-1 downto 0);
full : out std_logic;
empty : out std_logic
);
end component;
end technology;
library IEEE;
use IEEE.std_logic_1164.all;
library exemplar;
use exemplar.exemplar_1164.all;
 
package body technology is
function "+"(op_l, op_r: std_logic_vector) return std_logic_vector is
begin
return exemplar_1164."+"(op_l, op_r);
end;
function add_one(inp : std_logic_vector) return std_logic_vector is
variable one: std_logic_vector(inp'RANGE) := (others => '0');
begin
one(0) := '1';
return exemplar_1164."+"(inp,one);
end;
 
function is_zero(inp : std_logic_vector) return boolean is
variable zero: std_logic_vector(inp'RANGE) := (others => '0');
begin
return (inp = zero);
end;
 
function sl(l: std_logic_vector; r: integer) return std_logic_vector is
begin
return exemplar_1164.sl(l,r);
end;
-- procedure inc(data : inout std_logic_vector) is
-- begin
-- data := addone(data);
-- end;
end package body technology;
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library exemplar;
use exemplar.exemplar_1164.all;
 
library lpm;
use lpm.all;
 
entity fifo is
generic (fifo_width : positive;
used_width : positive;
fifo_depth : positive
);
port (d_in : in std_logic_vector(fifo_width-1 downto 0);
clk : in std_logic;
wr : in std_logic;
rd : in std_logic;
a_clr : in std_logic := '0';
s_clr : in std_logic := '0';
d_out : out std_logic_vector(fifo_width-1 downto 0);
used : out std_logic_vector(used_width-1 downto 0);
full : out std_logic;
empty : out std_logic
);
end fifo;
 
architecture altera of fifo is
component lpm_fifo
generic (LPM_WIDTH : positive;
LPM_WIDTHU : positive;
LPM_NUMWORDS : positive;
LPM_SHOWAHEAD : string := "OFF";
LPM_TYPE : string := "LPM_FIFO";
LPM_HINT : string := "UNUSED");
port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
CLOCK : in std_logic;
WRREQ : in std_logic;
RDREQ : in std_logic;
ACLR : in std_logic;
SCLR : in std_logic;
Q : out std_logic_vector(LPM_WIDTH-1 downto 0);
USEDW : out std_logic_vector(LPM_WIDTHU-1 downto 0);
FULL : out std_logic;
EMPTY : out std_logic);
end component;
begin
altera_fifo: lpm_fifo
generic map (
LPM_WIDTH => fifo_width,
LPM_WIDTHU => used_width,
LPM_NUMWORDS => fifo_depth,
LPM_SHOWAHEAD => "OFF",
LPM_TYPE => "LPM_FIFO",
LPM_HINT => "UNUSED"
)
port map (
DATA => d_in,
CLOCK => clk,
WRREQ => wr,
RDREQ => rd,
ACLR => a_clr,
SCLR => s_clr,
Q => d_out,
USEDW => used,
FULL => full,
EMPTY => empty
);
end altera;
 
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library altera_exemplar;
use altera_exemplar.all;
 
entity d_ff is
port ( d : in STD_LOGIC;
clk: in STD_LOGIC;
ena: in STD_LOGIC := '1';
clr: in STD_LOGIC := '0';
pre: in STD_LOGIC := '0';
q : out STD_LOGIC
);
end d_ff;
 
architecture altera of d_ff is
component dffe
port ( D : in STD_LOGIC;
CLK: in STD_LOGIC;
ENA: in STD_LOGIC;
CLRN: in STD_LOGIC;
PRN: in STD_LOGIC;
Q : out STD_LOGIC);
end component;
signal clrn,prn: std_logic;
begin
clrn <= not clr;
prn <= not pre;
ff: dffe port map (
D => d,
CLK => clk,
ENA => ena,
CLRN => clrn,
PRN => prn,
Q => q
);
end altera;
 
-- Sythetizer library. Contains STD_LOGIC arithmetics
 
/tags/a01/video_engine.vhd
0,0 → 1,223
--
-- File: video_engine.vhd
--
-- (c) Copyright Andras Tantos <andras_tantos@yahoo.com> 2001/03/31
-- This code is distributed under the terms and conditions of the GNU General Public Lince.
--
 
library IEEE;
use IEEE.std_logic_1164.all;
 
library work;
use work.technology.all;
 
entity video_engine is
generic (
v_mem_width: positive := 16;
v_addr_width: positive:= 20;
fifo_size: positive := 256;
dual_scan_fifo_size: positive := 256
);
port (
clk: in std_logic;
clk_en: in std_logic := '1';
reset: in std_logic := '0';
total: in std_logic_vector(v_addr_width-1 downto 0); -- total video memory size in bytes 7..0
fifo_treshold: in std_logic_vector(7 downto 0); -- priority change threshold
bpp: in std_logic_vector(1 downto 0); -- number of bits makes up a pixel valid values: 1,2,4,8
multi_scan: in std_logic_vector(1 downto 0); -- number of repeated scans
 
hbs: in std_logic_vector(7 downto 0);
hss: in std_logic_vector(7 downto 0);
hse: in std_logic_vector(7 downto 0);
htotal: in std_logic_vector(7 downto 0);
vbs: in std_logic_vector(7 downto 0);
vss: in std_logic_vector(7 downto 0);
vse: in std_logic_vector(7 downto 0);
vtotal: in std_logic_vector(7 downto 0);
pps: in std_logic_vector(7 downto 0);
 
high_prior: out std_logic; -- signals to the memory arbitrer to give high
-- priority to the video engine
v_mem_rd: out std_logic; -- video memory read request
v_mem_rdy: in std_logic; -- video memory data ready
v_mem_addr: out std_logic_vector (v_addr_width-1 downto 0); -- video memory address
v_mem_data: in std_logic_vector (v_mem_width-1 downto 0); -- video memory data
 
h_sync: out std_logic;
h_blank: out std_logic;
v_sync: out std_logic;
v_blank: out std_logic;
h_tc: out std_logic;
v_tc: out std_logic;
blank: out std_logic;
video_out: out std_logic_vector (7 downto 0) -- video output binary signal (unused bits are forced to 0)
);
end video_engine;
 
architecture video_engine of video_engine is
component hv_sync
port (
clk: in std_logic;
pix_clk_en: in std_logic := '1';
reset: in std_logic := '0';
hbs: in std_logic_vector(7 downto 0);
hss: in std_logic_vector(7 downto 0);
hse: in std_logic_vector(7 downto 0);
htotal: in std_logic_vector(7 downto 0);
vbs: in std_logic_vector(7 downto 0);
vss: in std_logic_vector(7 downto 0);
vse: in std_logic_vector(7 downto 0);
vtotal: in std_logic_vector(7 downto 0);
h_sync: out std_logic;
h_blank: out std_logic;
v_sync: out std_logic;
v_blank: out std_logic;
h_tc: out std_logic;
v_tc: out std_logic;
blank: out std_logic
);
end component;
 
component mem_reader
generic (
v_mem_width: positive := 16;
v_addr_width: positive:= 20;
fifo_size: positive := 256;
dual_scan_fifo_size: positive := 256
);
port (
clk: in std_logic;
clk_en: in std_logic;
pix_clk_en: in std_logic;
reset: in std_logic := '0';
total: in std_logic_vector(v_addr_width-1 downto 0); -- total video memory size in bytes 7..0
fifo_treshold: in std_logic_vector(7 downto 0); -- priority change threshold
bpp: in std_logic_vector(1 downto 0); -- number of bits makes up a pixel valid values: 1,2,4,8
multi_scan: in std_logic_vector(1 downto 0); -- number of repeated scans
high_prior: out std_logic; -- signals to the memory arbitrer to give high
-- priority to the video engine
v_mem_rd: out std_logic; -- video memory read request
v_mem_rdy: in std_logic; -- video memory data ready
v_mem_addr: out std_logic_vector (v_addr_width-1 downto 0); -- video memory address
v_mem_data: in std_logic_vector (v_mem_width-1 downto 0); -- video memory data
blank: in std_logic; -- video sync generator blank output
h_tc: in std_logic; -- horizontal sync pulse. Must be 1 clock wide!
video_out: out std_logic_vector (7 downto 0) -- video output binary signal (unused bits are forced to 0)
);
end component;
 
signal pix_clk_en: std_logic;
 
signal i_h_sync: std_logic;
signal i_h_blank: std_logic;
signal i_v_sync: std_logic;
signal i_v_blank: std_logic;
signal i_h_tc: std_logic;
signal i_v_tc: std_logic;
signal i_blank: std_logic;
begin
pps_gen: process is
variable cnt: std_logic_vector(3 downto 0);
begin
wait until clk'EVENT and clk = '1';
if (reset = '1') then
cnt := (others => '0');
pix_clk_en <= '0';
else
if (clk_en = '0') then
pix_clk_en <= '0';
else
if (cnt = pps(3 downto 0)) then
cnt := (others => '0');
pix_clk_en <= '1';
else
cnt := add_one(cnt);
pix_clk_en <= '0';
end if;
end if;
end if;
end process;
mem_engine : mem_reader
generic map (
v_mem_width => v_mem_width,
v_addr_width => v_addr_width,
fifo_size => fifo_size,
dual_scan_fifo_size => dual_scan_fifo_size
)
port map (
clk => clk,
clk_en => clk_en,
pix_clk_en => pix_clk_en,
reset => reset,
total => total,
fifo_treshold => fifo_treshold,
bpp => bpp,
multi_scan => multi_scan,
high_prior => high_prior,
v_mem_rd => v_mem_rd,
v_mem_rdy => v_mem_rdy,
v_mem_addr => v_mem_addr,
v_mem_data => v_mem_data,
blank => i_blank,
h_tc => i_h_tc,
video_out => video_out
);
 
sync_engine : hv_sync
port map (
clk => clk,
pix_clk_en => pix_clk_en,
reset => reset,
hbs => hbs,
hss => hss,
hse => hse,
htotal => htotal,
vbs => vbs,
vss => vss,
vse => vse,
vtotal => vtotal,
h_sync => i_h_sync,
h_blank => i_h_blank,
v_sync => i_v_sync,
v_blank => i_v_blank,
h_tc => i_h_tc,
v_tc => i_v_tc,
blank => i_blank
);
 
-- Delay all sync signals with one pixel. That's becouse of the syncron output of the mem_reader
sync_delay: process is
begin
wait until (clk'EVENT and clk='1');
if (reset = '1') then
h_sync <= '0';
h_blank <= '1';
v_sync <= '0';
v_blank <= '1';
blank <= '1';
elsif (pix_clk_en = '1') then
h_sync <= i_h_sync;
h_blank <= i_h_blank;
v_sync <= i_v_sync;
v_blank <= i_v_blank;
blank <= i_blank;
end if;
end process;
h_tc <= i_h_tc;
v_tc <= i_v_tc;
 
end video_engine;
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.