-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbridge_buffer.vhdl
More file actions
128 lines (115 loc) · 4.26 KB
/
bridge_buffer.vhdl
File metadata and controls
128 lines (115 loc) · 4.26 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY bridge_buffer IS
GENERIC (
ram_len : NATURAL := 17
);
PORT (
clk : IN STD_LOGIC; -- fpga clock
rst : IN STD_LOGIC; -- fpga reset
clk_in : IN STD_LOGIC; -- protocal clock
clk_out : IN STD_LOGIC; -- new clock
data_out : OUT STD_LOGIC; -- data to fake enc
data_in : IN STD_LOGIC -- data from fake rob
);
END bridge_buffer;
ARCHITECTURE rtl OF bridge_buffer IS
TYPE ram_type IS ARRAY (0 TO ram_len - 1) OF STD_LOGIC;
SIGNAL ram : ram_type;
TYPE edge_type IS ARRAY (0 TO 1) OF STD_LOGIC;
SIGNAL edge_wr : edge_type; -- edge detector for protocal clock in
SIGNAL edge_rd : edge_type; -- edge detector for protocal clock out
SUBTYPE index_type IS INTEGER RANGE ram_type'range;
SIGNAL wr_i : index_type; -- writer index
SIGNAL rd_i : index_type; -- reader index
SIGNAL h_period : INTEGER;
SIGNAL tmp_h_period : INTEGER;
SIGNAL count : INTEGER RANGE 0 TO INTEGER'HIGH;
SIGNAL realign : STD_LOGIC := '0';
BEGIN
PROC_EDGE :
PROCESS(clk) BEGIN
IF RISING_EDGE(clk) THEN
IF rst = '1' THEN
edge_wr(1) <= '1';
edge_wr(0) <= '1';
edge_rd(1) <= '1';
edge_rd(0) <= '1'; -- so as to capture the first falling edge to come
ELSE
edge_wr(1) <= edge_wr(0);
edge_wr(0) <= clk_out;
edge_rd(1) <= edge_rd(0);
edge_rd(0) <= clk_in;
END IF;
END IF;
END PROCESS;
PROC_H_PERIOD :
PROCESS(clk) BEGIN
IF RISING_EDGE(clk) THEN
IF rst = '1' THEN
h_period <= 0;
tmp_h_period <= 0;
ELSE
IF (edge_wr(0) = '0' AND edge_wr(1) = '1') OR (edge_wr(0) = '1' AND edge_wr(1) = '0') THEN
h_period <= tmp_h_period;
tmp_h_period <= 0;
ELSE
tmp_h_period <= tmp_h_period + 1;
END IF;
END IF;
END IF;
END PROCESS;
PROC_ADJUST :
PROCESS(clk) BEGIN
IF RISING_EDGE(clk) THEN
IF rst = '1' THEN
count <= 0;
ELSE
IF (edge_wr(0) = '0' AND edge_wr(1) = '1') OR (edge_wr(0) = '1' AND edge_wr(1) = '0') THEN
count <= 0;
ELSIF count < 4 * h_period THEN
count <= count + 1;
ELSE
count <= count;
END IF;
IF count > 2 * h_period AND count < 3 * h_period THEN
realign <= '1';
ELSE
realign <= '0';
END IF;
END IF;
END IF;
END PROCESS;
PROC_WRITE :
PROCESS(clk) BEGIN
IF RISING_EDGE(clk) THEN
IF rst = '1' OR realign = '1' THEN
wr_i <= 0;
ELSIF edge_wr(0) = '0' AND edge_wr(1) = '1' THEN
ram(wr_i) <= data_in; -- write ram
ELSIF edge_wr(1) = '0' AND edge_wr(0) = '1' THEN
IF wr_i >= ram_len THEN
wr_i <= 0;
ELSE
wr_i <= wr_i + 1;
END IF; -- move pointer
END IF;
END IF;
END PROCESS;
PROC_READ :
PROCESS(clk) BEGIN
IF RISING_EDGE(clk) THEN
IF rst = '1' OR realign = '1' THEN
rd_i <= 1;
data_out <= '1';
ELSIF edge_rd(0) = '0' AND edge_rd(1) = '1' THEN
data_out <= ram(rd_i);
IF rd_i >= ram_len THEN
rd_i <= 1; -- read starts at index 1
ELSE
rd_i <= rd_i + 1;
END IF; -- move pointer
END IF;
END IF;
END PROCESS;
END rtl;