1 |
2 |
dmitryr |
// ========== Copyright Header Begin ==========================================
|
2 |
|
|
//
|
3 |
|
|
// OpenSPARC T1 Processor File: ucb_bus_in.v
|
4 |
|
|
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
|
5 |
|
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
|
6 |
|
|
//
|
7 |
|
|
// The above named program is free software; you can redistribute it and/or
|
8 |
|
|
// modify it under the terms of the GNU General Public
|
9 |
|
|
// License version 2 as published by the Free Software Foundation.
|
10 |
|
|
//
|
11 |
|
|
// The above named program is distributed in the hope that it will be
|
12 |
|
|
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 |
|
|
// General Public License for more details.
|
15 |
|
|
//
|
16 |
|
|
// You should have received a copy of the GNU General Public
|
17 |
|
|
// License along with this work; if not, write to the Free Software
|
18 |
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
19 |
|
|
//
|
20 |
|
|
// ========== Copyright Header End ============================================
|
21 |
|
|
////////////////////////////////////////////////////////////////////////
|
22 |
|
|
/*
|
23 |
|
|
// Module Name: ucb_bus_in (ucb bus inbound interface block)
|
24 |
|
|
// Description: This interface block is instaniated by the
|
25 |
|
|
// UCB modules and IO Bridge to receive packets
|
26 |
|
|
// on the UCB bus.
|
27 |
|
|
*/
|
28 |
|
|
////////////////////////////////////////////////////////////////////////
|
29 |
|
|
// Global header file includes
|
30 |
|
|
////////////////////////////////////////////////////////////////////////
|
31 |
|
|
`include "sys.h" // system level definition file which contains the
|
32 |
|
|
// time scale definition
|
33 |
|
|
|
34 |
|
|
////////////////////////////////////////////////////////////////////////
|
35 |
|
|
// Local header file includes / local defines
|
36 |
|
|
////////////////////////////////////////////////////////////////////////
|
37 |
|
|
|
38 |
|
|
////////////////////////////////////////////////////////////////////////
|
39 |
|
|
// Interface signal list declarations
|
40 |
|
|
////////////////////////////////////////////////////////////////////////
|
41 |
|
|
module ucb_bus_in (/*AUTOARG*/
|
42 |
|
|
// Outputs
|
43 |
|
|
stall, indata_buf_vld, indata_buf,
|
44 |
|
|
// Inputs
|
45 |
|
|
rst_l, clk, vld, data, stall_a1
|
46 |
|
|
);
|
47 |
|
|
|
48 |
|
|
// synopsys template
|
49 |
|
|
|
50 |
|
|
parameter UCB_BUS_WIDTH = 32;
|
51 |
|
|
parameter REG_WIDTH = 64;
|
52 |
|
|
|
53 |
|
|
|
54 |
|
|
////////////////////////////////////////////////////////////////////////
|
55 |
|
|
// Signal declarations
|
56 |
|
|
////////////////////////////////////////////////////////////////////////
|
57 |
|
|
// Global interface
|
58 |
|
|
input rst_l;
|
59 |
|
|
input clk;
|
60 |
|
|
|
61 |
|
|
|
62 |
|
|
// UCB bus interface
|
63 |
|
|
input vld;
|
64 |
|
|
input [UCB_BUS_WIDTH-1:0] data;
|
65 |
|
|
output stall;
|
66 |
|
|
|
67 |
|
|
|
68 |
|
|
// Local interface
|
69 |
|
|
output indata_buf_vld;
|
70 |
|
|
output [REG_WIDTH+63:0] indata_buf;
|
71 |
|
|
input stall_a1;
|
72 |
|
|
|
73 |
|
|
|
74 |
|
|
// Internal signals
|
75 |
|
|
wire vld_d1;
|
76 |
|
|
wire stall_d1;
|
77 |
|
|
wire [UCB_BUS_WIDTH-1:0] data_d1;
|
78 |
|
|
wire skid_buf0_en;
|
79 |
|
|
wire vld_buf0;
|
80 |
|
|
wire [UCB_BUS_WIDTH-1:0] data_buf0;
|
81 |
|
|
wire skid_buf1_en;
|
82 |
|
|
wire vld_buf1;
|
83 |
|
|
wire [UCB_BUS_WIDTH-1:0] data_buf1;
|
84 |
|
|
wire skid_buf0_sel;
|
85 |
|
|
wire skid_buf1_sel;
|
86 |
|
|
wire vld_mux;
|
87 |
|
|
wire [UCB_BUS_WIDTH-1:0] data_mux;
|
88 |
|
|
wire [(REG_WIDTH+64)/UCB_BUS_WIDTH-1:0] indata_vec_next;
|
89 |
|
|
wire [(REG_WIDTH+64)/UCB_BUS_WIDTH-1:0] indata_vec;
|
90 |
|
|
wire [REG_WIDTH+63:0] indata_buf_next;
|
91 |
|
|
wire indata_vec0_d1;
|
92 |
|
|
|
93 |
|
|
|
94 |
|
|
////////////////////////////////////////////////////////////////////////
|
95 |
|
|
// Code starts here
|
96 |
|
|
////////////////////////////////////////////////////////////////////////
|
97 |
|
|
/************************************************************
|
98 |
|
|
* UCB bus interface flops
|
99 |
|
|
* This is to make signals going between IOB and UCB flop-to-flop
|
100 |
|
|
* to improve timing.
|
101 |
|
|
************************************************************/
|
102 |
|
|
dffrle_ns #(1) vld_d1_ff (.din(vld),
|
103 |
|
|
.rst_l(rst_l),
|
104 |
|
|
.en(~stall_d1),
|
105 |
|
|
.clk(clk),
|
106 |
|
|
.q(vld_d1));
|
107 |
|
|
|
108 |
|
|
dffe_ns #(UCB_BUS_WIDTH) data_d1_ff (.din(data),
|
109 |
|
|
.en(~stall_d1),
|
110 |
|
|
.clk(clk),
|
111 |
|
|
.q(data_d1));
|
112 |
|
|
|
113 |
|
|
dffrl_ns #(1) stall_ff (.din(stall_a1),
|
114 |
|
|
.clk(clk),
|
115 |
|
|
.rst_l(rst_l),
|
116 |
|
|
.q(stall));
|
117 |
|
|
|
118 |
|
|
dffrl_ns #(1) stall_d1_ff (.din(stall),
|
119 |
|
|
.clk(clk),
|
120 |
|
|
.rst_l(rst_l),
|
121 |
|
|
.q(stall_d1));
|
122 |
|
|
|
123 |
|
|
|
124 |
|
|
/************************************************************
|
125 |
|
|
* Skid buffer
|
126 |
|
|
* We need a two deep skid buffer to handle stalling.
|
127 |
|
|
************************************************************/
|
128 |
|
|
// Assertion: stall has to be deasserted for more than 1 cycle
|
129 |
|
|
// ie time between two separate stalls has to be
|
130 |
|
|
// at least two cycles. Otherwise, contents from
|
131 |
|
|
// skid buffer will be lost.
|
132 |
|
|
|
133 |
|
|
// Buffer 0
|
134 |
|
|
assign skid_buf0_en = stall_a1 & ~stall;
|
135 |
|
|
|
136 |
|
|
dffrle_ns #(1) vld_buf0_ff (.din(vld_d1),
|
137 |
|
|
.rst_l(rst_l),
|
138 |
|
|
.en(skid_buf0_en),
|
139 |
|
|
.clk(clk),
|
140 |
|
|
.q(vld_buf0));
|
141 |
|
|
|
142 |
|
|
dffe_ns #(UCB_BUS_WIDTH) data_buf0_ff (.din(data_d1),
|
143 |
|
|
.en(skid_buf0_en),
|
144 |
|
|
.clk(clk),
|
145 |
|
|
.q(data_buf0));
|
146 |
|
|
|
147 |
|
|
// Buffer 1
|
148 |
|
|
dffrl_ns #(1) skid_buf1_en_ff (.din(skid_buf0_en),
|
149 |
|
|
.clk(clk),
|
150 |
|
|
.rst_l(rst_l),
|
151 |
|
|
.q(skid_buf1_en));
|
152 |
|
|
|
153 |
|
|
dffrle_ns #(1) vld_buf1_ff (.din(vld_d1),
|
154 |
|
|
.rst_l(rst_l),
|
155 |
|
|
.en(skid_buf1_en),
|
156 |
|
|
.clk(clk),
|
157 |
|
|
.q(vld_buf1));
|
158 |
|
|
|
159 |
|
|
dffe_ns #(UCB_BUS_WIDTH) data_buf1_ff (.din(data_d1),
|
160 |
|
|
.en(skid_buf1_en),
|
161 |
|
|
.clk(clk),
|
162 |
|
|
.q(data_buf1));
|
163 |
|
|
|
164 |
|
|
|
165 |
|
|
/************************************************************
|
166 |
|
|
* Mux between skid buffer and interface flop
|
167 |
|
|
************************************************************/
|
168 |
|
|
// Assertion: stall has to be deasserted for more than 1 cycle
|
169 |
|
|
// ie time between two separate stalls has to be
|
170 |
|
|
// at least two cycles. Otherwise, contents from
|
171 |
|
|
// skid buffer will be lost.
|
172 |
|
|
|
173 |
|
|
assign skid_buf0_sel = ~stall_a1 & stall;
|
174 |
|
|
|
175 |
|
|
dffrl_ns #(1) skid_buf1_sel_ff (.din(skid_buf0_sel),
|
176 |
|
|
.clk(clk),
|
177 |
|
|
.rst_l(rst_l),
|
178 |
|
|
.q(skid_buf1_sel));
|
179 |
|
|
|
180 |
|
|
assign vld_mux = skid_buf0_sel ? vld_buf0 :
|
181 |
|
|
skid_buf1_sel ? vld_buf1 :
|
182 |
|
|
vld_d1;
|
183 |
|
|
|
184 |
|
|
assign data_mux = skid_buf0_sel ? data_buf0 :
|
185 |
|
|
skid_buf1_sel ? data_buf1 :
|
186 |
|
|
data_d1;
|
187 |
|
|
|
188 |
|
|
|
189 |
|
|
/************************************************************
|
190 |
|
|
* Assemble inbound data
|
191 |
|
|
************************************************************/
|
192 |
|
|
// valid vector
|
193 |
|
|
assign indata_vec_next = {vld_mux,
|
194 |
|
|
indata_vec[(REG_WIDTH+64)/UCB_BUS_WIDTH-1:1]};
|
195 |
|
|
dffrle_ns #((REG_WIDTH+64)/UCB_BUS_WIDTH) indata_vec_ff (.din(indata_vec_next),
|
196 |
|
|
.en(~stall_a1),
|
197 |
|
|
.rst_l(rst_l),
|
198 |
|
|
.clk(clk),
|
199 |
|
|
.q(indata_vec));
|
200 |
|
|
|
201 |
|
|
// data buffer
|
202 |
|
|
assign indata_buf_next = {data_mux,
|
203 |
|
|
indata_buf[REG_WIDTH+63:UCB_BUS_WIDTH]};
|
204 |
|
|
dffe_ns #(REG_WIDTH+64) indata_buf_ff (.din(indata_buf_next),
|
205 |
|
|
.en(~stall_a1),
|
206 |
|
|
.clk(clk),
|
207 |
|
|
.q(indata_buf));
|
208 |
|
|
|
209 |
|
|
// detect a new packet
|
210 |
|
|
dffrle_ns #(1) indata_vec0_d1_ff (.din(indata_vec[0]),
|
211 |
|
|
.rst_l(rst_l),
|
212 |
|
|
.en(~stall_a1),
|
213 |
|
|
.clk(clk),
|
214 |
|
|
.q(indata_vec0_d1));
|
215 |
|
|
|
216 |
|
|
assign indata_buf_vld = indata_vec[0] & ~indata_vec0_d1;
|
217 |
|
|
|
218 |
|
|
|
219 |
|
|
endmodule // ucb_bus_in
|