/
reg_file_pkg.vhd
115 lines (93 loc) · 3.99 KB
/
reg_file_pkg.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
-- -------------------------------------------------------------------------------------------------
-- Copyright (c) Lukas Vik. All rights reserved.
--
-- This file is part of the hdl-modules project, a collection of reusable, high-quality,
-- peer-reviewed VHDL building blocks.
-- https://hdl-modules.com
-- https://github.com/hdl-modules/hdl-modules
-- -------------------------------------------------------------------------------------------------
-- Package with constants/types/functions for generic register file ecosystem.
-- -------------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library common;
use common.addr_pkg.all;
library math;
use math.math_pkg.all;
package reg_file_pkg is
constant reg_width : positive := 32;
subtype reg_t is std_ulogic_vector(reg_width - 1 downto 0);
type reg_vec_t is array (integer range <>) of reg_t;
type reg_type_t is (
-- Bus can read a value that fabric provides
r,
-- Bus can write a value that is available for fabric usage
w,
-- Bus can write a value and read it back. The written value is available for fabric usage
r_w,
-- Bus can write a value that is asserted for one cycle in fabric
wpulse,
-- Bus can read a value that fabric provides.
-- Bus can write a value that is asserted for one cycle in fabric.
r_wpulse
);
function is_read_type(reg_type : reg_type_t) return boolean;
function is_write_type(reg_type : reg_type_t) return boolean;
function is_write_pulse_type(reg_type : reg_type_t) return boolean;
function is_fabric_gives_value_type(reg_type : reg_type_t) return boolean;
type reg_definition_t is record
idx : natural;
reg_type : reg_type_t;
end record;
type reg_definition_vec_t is array (natural range <>) of reg_definition_t;
function get_highest_idx(regs : reg_definition_vec_t) return natural;
function get_addr_mask(regs : reg_definition_vec_t) return addr_t;
function to_addr_and_mask_vec(regs : reg_definition_vec_t) return addr_and_mask_vec_t;
end;
package body reg_file_pkg is
function is_read_type(reg_type : reg_type_t) return boolean is
begin
return reg_type = r or reg_type = r_w or reg_type = r_wpulse;
end function;
function is_write_type(reg_type : reg_type_t) return boolean is
begin
return reg_type = w or reg_type = r_w or reg_type = wpulse or reg_type = r_wpulse;
end function;
function is_write_pulse_type(reg_type : reg_type_t) return boolean is
begin
return reg_type = wpulse or reg_type = r_wpulse;
end function;
function is_fabric_gives_value_type(reg_type : reg_type_t) return boolean is
begin
return reg_type = r or reg_type = r_wpulse;
end function;
function get_highest_idx(regs : reg_definition_vec_t) return natural is
begin
assert regs(0).idx = 0 severity failure;
assert regs(regs'high).idx = regs'length - 1 severity failure;
return regs(regs'high).idx;
end function;
function get_addr_mask(regs : reg_definition_vec_t) return addr_t is
constant num_bits : positive := num_bits_needed(get_highest_idx(regs));
variable result : addr_t := (others => '0');
begin
-- Lowest bits are always zero since registers are 32-bits i.e. four-byte aligned.
result(num_bits + 2 - 1 downto 2) := (others => '1');
return result;
end function;
function to_addr_and_mask_vec(regs : reg_definition_vec_t) return addr_and_mask_vec_t is
constant mask : addr_t := get_addr_mask(regs);
variable result : addr_and_mask_vec_t(regs'range);
begin
for list_idx in regs'range loop
-- Registers are 32-bits i.e. four-byte aligned, hence the multiplication.
result(list_idx).addr := to_unsigned(4 * regs(list_idx).idx, result(list_idx).addr'length);
result(list_idx).mask := mask;
end loop;
assert sanity_check_address_and_mask(result)
report "Calculated address and mask are not valid. See printout above."
severity failure;
return result;
end function;
end;