You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
microwatt/peripherals/cordic/cordic_wb.vhdl

87 lines
2.8 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity cordic_wb is
port(
clk : in std_ulogic;
rst : in std_ulogic;
-- Wishbone IO interface (Microwatt)
wb_adr_i : in std_ulogic_vector(29 downto 0);
wb_dat_i : in std_ulogic_vector(31 downto 0);
wb_dat_o : out std_ulogic_vector(31 downto 0);
wb_we_i : in std_ulogic;
wb_stb_i : in std_ulogic;
wb_cyc_i : in std_ulogic;
wb_ack_o : out std_ulogic;
-- CORDIC core interface
cordic_x : out std_ulogic_vector(31 downto 0);
cordic_y : out std_ulogic_vector(31 downto 0);
cordic_start : out std_ulogic;
cordic_done : in std_ulogic;
cordic_result : in std_ulogic_vector(31 downto 0)
);
end entity cordic_wb;
architecture rtl of cordic_wb is
signal x_reg : std_ulogic_vector(31 downto 0) := (others => '0');
signal y_reg : std_ulogic_vector(31 downto 0) := (others => '0');
signal start_reg : std_ulogic := '0';
begin
-- Drive CORDIC core
cordic_x <= x_reg;
cordic_y <= y_reg;
cordic_start <= start_reg;
-- Wishbone slave
process(clk)
variable addr : std_ulogic_vector(2 downto 0);
begin
if rising_edge(clk) then
wb_ack_o <= '0';
if rst = '1' then
x_reg <= (others => '0');
y_reg <= (others => '0');
start_reg <= '0';
wb_dat_o <= (others => '0');
elsif wb_cyc_i = '1' and wb_stb_i = '1' then
wb_ack_o <= '1';
addr := wb_adr_i(4 downto 2); -- word offsets
if wb_we_i = '1' then
-- WRITE
case addr is
when "000" => x_reg <= wb_dat_i; -- 0x00
when "001" => y_reg <= wb_dat_i; -- 0x04
when "010" => start_reg <= wb_dat_i(0); -- 0x08
when others => null;
end case;
else
-- READ
case addr is
when "000" => wb_dat_o <= x_reg; -- 0x00
when "001" => wb_dat_o <= y_reg; -- 0x04
when "011" => wb_dat_o <= (31 downto 1 => '0') & cordic_done; -- 0x0C
when "100" => wb_dat_o <= cordic_result; -- 0x10
when others => wb_dat_o <= (others => '0');
end case;
end if;
end if;
-- Auto-clear start when done
if cordic_done = '1' then
start_reg <= '0';
end if;
end if;
end process;
end architecture rtl;