mm_avalon_sqrt.vhd 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. -- altera vhdl_input_version vhdl_2008
  2. library ieee;
  3. use ieee.std_logic_1164.all;
  4. use ieee.numeric_std.all;
  5. library lpm;
  6. USE lpm.lpm_components.all;
  7. LIBRARY altera_mf;
  8. USE altera_mf.altera_mf_components.all;
  9. use work.fifo_pkg.all;
  10. entity avalon_mm_sqrt is
  11. port (
  12. clk : in std_logic;
  13. res_n : in std_logic;
  14. --memory mapped slave
  15. address : in std_logic_vector(0 downto 0);
  16. write : in std_logic;
  17. read : in std_logic;
  18. writedata : in std_logic_vector(31 downto 0);
  19. readdata : out std_logic_vector(31 downto 0)
  20. );
  21. end entity;
  22. architecture rtl of avalon_mm_sqrt is
  23. constant CAPACITY : integer := 64;
  24. constant SHORT_ZERO : std_logic_vector(15 downto 0) := (others => '0');
  25. constant LONG_ZERO : std_logic_vector(47 downto 0) := (others => '0');
  26. component alt_sqrt
  27. port (
  28. clk : in std_logic;
  29. radical : in std_logic_vector(47 downto 0);
  30. q : out std_logic_vector(23 downto 0);
  31. remainder : out std_logic_vector(24 downto 0)
  32. );
  33. end component;
  34. signal reg_shift_request : std_logic_vector(15 downto 0) := SHORT_ZERO;
  35. signal reg_next_shift_request : std_logic_vector(15 downto 0);
  36. signal alt_sqrt_done : std_logic := '0';
  37. signal fifo_in : fifo_in_t := FIFO_IN_NOP;
  38. signal fifo_out : fifo_out_t;
  39. type alt_sqrt_out_t is
  40. record
  41. q : std_logic_vector(23 downto 0);
  42. remainder : std_logic_vector(24 downto 0);
  43. end record;
  44. signal alt_sqrt_in_radical : std_logic_vector(47 downto 0) := LONG_ZERO;
  45. signal alt_sqrt_out : alt_sqrt_out_t;
  46. signal alt_sqrt_result : std_logic_vector(31 downto 0) := ZERO;
  47. begin
  48. alt_fwft_fifo_inst : entity work.alt_fwft_fifo
  49. generic map (
  50. DATA_WIDTH => 32,
  51. NUM_ELEMENTS => CAPACITY
  52. )
  53. port map (
  54. aclr => not res_n,
  55. clock => clk,
  56. data => fifo_in.data,
  57. rdreq => fifo_in.rdreq,
  58. wrreq => fifo_in.wrreq,
  59. empty => fifo_out.empty,
  60. full => fifo_out.full,
  61. q => fifo_out.q
  62. );
  63. alt_sqrt_inst : component alt_sqrt
  64. port map (
  65. clk => clk,
  66. radical => alt_sqrt_in_radical,
  67. q => alt_sqrt_out.q,
  68. remainder => alt_sqrt_out.remainder
  69. );
  70. readdata <= fifo_out.q when address(0) else (0 => fifo_out.empty, others => '0');
  71. alt_sqrt_done <= reg_shift_request(15);
  72. fifo_in.wrreq <= alt_sqrt_done;
  73. fifo_in.data <= alt_sqrt_result;
  74. fifo_in.rdreq <= read and address(0) and not fifo_out.empty;
  75. sync : process(clk, res_n)
  76. begin
  77. if res_n = '0' then
  78. -- reset values
  79. reg_shift_request <= SHORT_ZERO;
  80. elsif rising_edge(clk) then
  81. -- register transfer
  82. reg_shift_request <= reg_next_shift_request;
  83. end if;
  84. end process;
  85. async : process(all)
  86. begin
  87. -- implement shift register for enqueue operations (to know when alt_sqrt is done)
  88. reg_next_shift_request(0) <= (not address(0)) and write;
  89. reg_next_shift_request(reg_shift_request'high downto 1) <= reg_shift_request(reg_shift_request'high - 1 downto 0);
  90. -- extend data by 16 bits and then shift up
  91. alt_sqrt_in_radical <= writedata & SHORT_ZERO;
  92. -- sign extend result
  93. --alt_sqrt_result <= std_logic_vector(shift_right(signed(alt_sqrt_out.q) & x"00", 8));
  94. alt_sqrt_result <= x"00" & alt_sqrt_out.q;
  95. end process;
  96. end architecture;