source: XOpenSparcT1/trunk/T1-common/common/ucb_bus_in.v @ 6

Revision 6, 7.1 KB checked in by pntsvt00, 13 years ago (diff)

versione iniziale opensparc

Line 
1// ========== 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////////////////////////////////////////////////////////////////////////
41module 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   
219endmodule // ucb_bus_in
Note: See TracBrowser for help on using the repository browser.