updated wiki url
[debian/gnuradio] / usrp2 / fpga / opencores / wb_zbt / wb_zbt.v
1 /*
2  * Multi-port ZBT SRAM WISHBONE controller
3  * Copyright (C) 2008 Sebastien Bourdeauducq - http://lekernel.net
4  * This file is part of Milkymist.
5  *
6  * Milkymist is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Library General Public License as published
8  * by the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22 module wb_zbt(
23         input               clk,
24         input               rst,
25         // Wishbone bus A, highest priority, with prefetch
26         input      [31:0]   wbA_adr_i,
27         input      [31:0]   wbA_dat_i,
28         output     [31:0]   wbA_dat_o,
29         input      [ 3:0]   wbA_sel_i,
30         input               wbA_cyc_i,
31         input               wbA_stb_i,
32         output              wbA_ack_o,
33         input               wbA_we_i,
34         // Wishbone bus B, lower priority
35         input      [31:0]   wbB_adr_i,
36         input      [31:0]   wbB_dat_i,
37         output     [31:0]   wbB_dat_o,
38         input      [ 3:0]   wbB_sel_i,
39         input               wbB_cyc_i,
40         input               wbB_stb_i,
41         output              wbB_ack_o,
42         input               wbB_we_i,
43         // Memory connection
44         output              sram_clk,
45         output     [17:0]   sram_a,
46         inout      [31:0]   sram_d,
47         output              sram_we,
48         output     [ 3:0]   sram_bw,
49         output              sram_adv,
50         output              sram_ce,
51         output              sram_oe,
52         output              sram_mode,
53         output              sram_zz
54 );
55
56 assign sram_clk = clk;
57 assign sram_oe = 1'b0;
58 assign sram_ce = 1'b0;
59 assign sram_adv = 1'b0;
60 assign sram_mode = 1'b0;
61 assign sram_zz = 1'b0;
62
63 /* Wishbone decoding */
64
65 wire busA_active;
66 wire busB_active;
67
68 assign busA_active = wbA_cyc_i & wbA_stb_i;
69 assign busB_active = wbB_cyc_i & wbB_stb_i;
70
71 /* Those are used to represent the state of the SRAM pipeline
72  * Bit 0 = Write Enable
73  * Bits 18..1 = Address
74  */
75 wire [18:0] pipeline_in;
76 reg [18:0] pipeline_internal;
77 reg [18:0] pipeline_out;
78
79 always @(posedge clk or posedge rst) begin
80         if(rst) begin
81                 pipeline_internal <= 0;
82                 pipeline_out <= 0;
83         end else begin
84                 pipeline_internal <= pipeline_in;
85                 pipeline_out <= pipeline_internal;
86         end
87 end
88
89 /* Pipeline contents decode */
90
91 wire inprogressA;
92 wire inprogressB;
93
94 assign inprogressA = (pipeline_internal[18:1] == wbA_adr_i[19:2]) & (pipeline_internal[0] == wbA_we_i);
95 assign inprogressB = (pipeline_internal[18:1] == wbB_adr_i[19:2]) & (pipeline_internal[0] == wbB_we_i);
96
97 wire hitA;
98 wire hitB;
99
100 assign hitA = (pipeline_out[18:1] == wbA_adr_i[19:2]) & (pipeline_out[0] == wbA_we_i);
101 assign hitB = (pipeline_out[18:1] == wbB_adr_i[19:2]) & (pipeline_out[0] == wbB_we_i);
102
103 /* Access arbitration */
104
105 wire [1:0] bus_request;
106
107 assign bus_request[0] = busA_active & ~inprogressA & ~hitA;
108 assign bus_request[1] = busB_active & ~inprogressB & ~hitB;
109
110 wire prefetch_enable;
111 reg [17:0] prefetch_address;
112
113 assign prefetch_enable = ~bus_request[0] & ~bus_request[1];
114 always @(posedge clk) begin
115         if(prefetch_enable)
116                 prefetch_address <= wbA_adr_i[19:2] + 2;
117         else
118                 prefetch_address <= wbA_adr_i[19:2] + 1;
119 end
120
121 wire [1:0] bus_selected;
122
123 assign bus_selected[0] = bus_request[0];
124 assign bus_selected[1] = bus_request[1] & ~bus_request[0];
125
126 assign pipeline_in[18:1] = ({18{bus_selected[0]}} & wbA_adr_i[19:2])
127         | ({18{bus_selected[1]}} & wbB_adr_i[19:2])
128         | ({18{prefetch_enable}} & prefetch_address);
129 assign pipeline_in[0] = (bus_selected[0] & wbA_we_i)|(bus_selected[1] & wbB_we_i);
130
131 /* SRAM control */
132
133 assign sram_a = pipeline_in[18:1];
134 assign sram_bw = ~(({4{bus_selected[0]}} & wbA_sel_i)|({4{bus_selected[1]}} & wbB_sel_i));
135 assign sram_we = ~pipeline_in[0];
136
137 /* SRAM data */
138
139 wire [31:0] bus_wdata;
140
141 assign wbA_ack_o = busA_active & hitA;
142 assign wbB_ack_o = busB_active & hitB;
143
144 assign bus_wdata = ({32{hitA}} & wbA_dat_i)|({32{hitB}} & wbB_dat_i);
145 assign sram_d = pipeline_out[0] ? bus_wdata : 32'hzzzzzzzz;
146 assign wbA_dat_o = sram_d;
147 assign wbB_dat_o = sram_d;
148
149 endmodule