URL
https://opencores.org/ocsvn/bitserial/bitserial/trunk
Subversion Repositories bitserial
[/] [bitserial/] [trunk/] [util.vhd] - Rev 2
Compare with Previous | Blame | View Log
-- File: util.vhd -- Author: Richard James Howe -- Repository: https://github.com/howerj/bit-serial -- License: MIT -- Description: Utility module, mostly taken from another project -- of mine, <https://github.com/howerj/forth-cpu>. library ieee, work; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use std.textio.all; package util is -- Not all modules will need every generic specified here, even so it -- is easier to group the common generics in one structure. type common_generics is record clock_frequency: positive; -- clock frequency of module clock delay: time; -- gate delay for simulation purposes asynchronous_reset: boolean; -- use asynchronous reset if true end record; constant default_settings: common_generics := ( clock_frequency => 100_000_000, delay => 0 ns, asynchronous_reset => true ); type file_format is (FILE_HEX, FILE_BINARY, FILE_NONE); component single_port_block_ram is generic (g: common_generics; addr_length: positive := 12; data_length: positive := 16; file_name: string := "memory.bin"; file_type: file_format := FILE_BINARY); port ( clk: in std_ulogic; dwe: in std_ulogic; dre: in std_ulogic; addr: in std_ulogic_vector(addr_length - 1 downto 0); din: in std_ulogic_vector(data_length - 1 downto 0); dout: out std_ulogic_vector(data_length - 1 downto 0) := (others => '0')); end component; function hex_char_to_std_ulogic_vector_tb(hc: character) return std_ulogic_vector; end; package body util is function hex_char_to_std_ulogic_vector_tb(hc: character) return std_ulogic_vector is variable slv: std_ulogic_vector(3 downto 0); begin case hc is when '0' => slv := "0000"; when '1' => slv := "0001"; when '2' => slv := "0010"; when '3' => slv := "0011"; when '4' => slv := "0100"; when '5' => slv := "0101"; when '6' => slv := "0110"; when '7' => slv := "0111"; when '8' => slv := "1000"; when '9' => slv := "1001"; when 'A' => slv := "1010"; when 'a' => slv := "1010"; when 'B' => slv := "1011"; when 'b' => slv := "1011"; when 'C' => slv := "1100"; when 'c' => slv := "1100"; when 'D' => slv := "1101"; when 'd' => slv := "1101"; when 'E' => slv := "1110"; when 'e' => slv := "1110"; when 'F' => slv := "1111"; when 'f' => slv := "1111"; when others => slv := "XXXX"; end case; assert (slv /= "XXXX") report " not a valid hex character: " & hc severity failure; return slv; end; end; library ieee, work; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use std.textio.all; use work.util.all; entity single_port_block_ram is generic (g: common_generics; addr_length: positive := 12; data_length: positive := 16; file_name: string := "memory.bin"; file_type: file_format := FILE_BINARY); port ( clk: in std_ulogic; dwe: in std_ulogic; dre: in std_ulogic; addr: in std_ulogic_vector(addr_length - 1 downto 0); din: in std_ulogic_vector(data_length - 1 downto 0); dout: out std_ulogic_vector(data_length - 1 downto 0) := (others => '0')); end entity; architecture behav of single_port_block_ram is constant ram_size: positive := 2 ** addr_length; type ram_type is array ((ram_size - 1 ) downto 0) of std_ulogic_vector(data_length - 1 downto 0); impure function initialize_ram(the_file_name: in string; the_file_type: in file_format) return ram_type is variable ram_data: ram_type; file in_file: text is in the_file_name; variable input_line: line; variable tmp: bit_vector(data_length - 1 downto 0); variable c: character; variable slv: std_ulogic_vector(data_length - 1 downto 0); begin for i in 0 to ram_size - 1 loop if the_file_type = FILE_NONE then ram_data(i):=(others => '0'); elsif not endfile(in_file) then readline(in_file,input_line); if the_file_type = FILE_BINARY then read(input_line, tmp); ram_data(i) := std_ulogic_vector(to_stdlogicvector(tmp)); elsif the_file_type = FILE_HEX then -- hexadecimal assert (data_length mod 4) = 0 report "(data_length%4)!=0" severity failure; for j in 1 to (data_length/4) loop c:= input_line((data_length/4) - j + 1); slv((j*4)-1 downto (j*4)-4) := hex_char_to_std_ulogic_vector_tb(c); end loop; ram_data(i) := slv; else report "Incorrect file type given: " & file_format'image(the_file_type) severity failure; end if; else ram_data(i) := (others => '0'); end if; end loop; file_close(in_file); return ram_data; end function; shared variable ram: ram_type := initialize_ram(file_name, file_type); begin block_ram: process(clk) begin if rising_edge(clk) then if dwe = '1' then ram(to_integer(unsigned(addr))) := din; end if; if dre = '1' then dout <= ram(to_integer(unsigned(addr))) after g.delay; else dout <= (others => '0') after g.delay; end if; end if; end process; end architecture;