Forum Discussion
Altera_Forum
Honored Contributor
10 years agoHi,
I don't see the use of such a Qsys component, but anyway, below is a proposed VHDL component for the implementation. It has three slave registers, two for the input operands (readable and writable) and one for the result (only readable). I haven't tested the code, so it may contain syntax or other errors, but it should give you the idea. Bye, Philipp EDIT: Sorry, I missed the second page of the thread. I'll still leave my post here for reference, maybe it is of use anyway.library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--! This entity is a Qsys core for a simple adder.
--! Register map (word addresses):
--! 0x0: Operand A (RW)
--! 0x1: Operand B (RW)
--! 0x2: Result (RO)
--! 0x3: Unused
entity udc_dac is
generic (
--! Width of the Avalon data bus.
DATA_W : positive := 32;
--! Width of the Avalon address bus. Every address corresponds to
--! one 32-bit word (so the address space in bytes is actually
--! 4 times larger).
ADDR_W : positive := 2
);
port (
-- System signals.
--! Master clock input, all logic is contained in this clock domain.
clk : in std_logic;
--! Asynchronous reset input, resets the internal logic.
reset : in std_logic;
-- Avalon slave interface signals.
--! Avalon read request. Reads are performed with a single waitstate
--! (wait 1).
read_ava : in std_logic;
--! Avalon write request.
write_ava : in std_logic;
--! Avalon address input.
address_ava : in std_logic_vector(ADDR_W-1 downto 0);
--! Avalon data input.
writedata_ava : in std_logic_vector(DATA_W-1 downto 0);
--! Avalon data output.
readdata_ava : out std_logic_vector(DATA_W-1 downto 0)
);
end entity;
architecture behav of udc_dac is
-- Operand registers.
signal op_a, op_b : unsigned(DATA_W-1 downto 0) := (others => '0');
-- Result register.
signal result : unsigned(DATA_W-1 downto 0) := (others => '0');
begin
-- Avalon read transaction handler.
avard : process(clk, reset) is
variable addr : natural range 0 to 3;
begin
if reset = '1' then
readdata_ava <= (others => '0');
elsif rising_edge(clk) then
if read_ava = '1' then
addr := to_integer(unsigned(address_ava));
case addr is
when 0 => readdata_ava <= std_logic_vector(op_a);
when 1 => readdata_ava <= std_logic_vector(op_b);
when 2 => readdata_ava <= std_logic_vector(result);
when others => readdata_ava <= (others => '0');
end case;
end if;
end if;
end process;
-- Avalon write transaction handler.
avawr : process(clk, reset) is
variable addr : natural range 0 to 3;
begin
if reset = '1' then
dac_value <= (others => (others => '0'));
elsif rising_edge(clk) then
if write_ava = '1' then
addr := to_integer(unsigned(address_ava));
case addr is
when 0 => op_a <= unsigned(writedata_ava);
when 1 => op_b <= unsigned(writedata_ava);
when others => -- Ignored.
end case;
end if;
end if;
end process;
-- Calculation.
calc: process(clk, reset) is
begin
if reset = '1' then
result <= (others => '0');
elsif rising_edge(clk) then
result <= op_a + op_b;
end if;
end process;
end architecture;