OpenCores
URL https://opencores.org/ocsvn/sockit_owm/sockit_owm/trunk

Subversion Repositories sockit_owm

[/] [sockit_owm/] [trunk/] [hdl/] [sockit_owm.v] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 iztok
//////////////////////////////////////////////////////////////////////////////
2
//                                                                          //
3
//  Minimalistic 1-wire (onewire) master with Avalon MM bus interface       //
4
//                                                                          //
5
//  Copyright (C) 2010  Iztok Jeras                                         //
6
//                                                                          //
7
//////////////////////////////////////////////////////////////////////////////
8
//                                                                          //
9
//  This RTL is free hardware: you can redistribute it and/or modify        //
10
//  it under the terms of the GNU Lesser General Public License             //
11
//  as published by the Free Software Foundation, either                    //
12
//  version 3 of the License, or (at your option) any later version.        //
13
//                                                                          //
14
//  This RTL is distributed in the hope that it will be useful,             //
15
//  but WITHOUT ANY WARRANTY; without even the implied warranty of          //
16
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
17
//  GNU General Public License for more details.                            //
18
//                                                                          //
19
//  You should have received a copy of the GNU General Public License       //
20
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
21
//                                                                          //
22
//////////////////////////////////////////////////////////////////////////////
23
 
24
 
25
//////////////////////////////////////////////////////////////////////////////
26
//                                                                          //
27
// The clock divider parameter is computed with the next formula:           //
28
//                                                                          //
29 3 iztok
// CDR_N = f_CLK * BTP_N - 1  (example: CDR_N = 1MHz * 5.0us - 1 = 5-1)     //
30
// CDR_O = f_CLK * BTP_O - 1  (example: CDR_O = 1MHz * 1.0us - 1 = 1-1)     //
31 2 iztok
//                                                                          //
32
// If the dividing factor is not a round integer, than the timing of the    //
33
// controller will be slightly off, and would support only a subset of      //
34
// 1-wire devices with timing closer to the typical 30us slot.              //
35
//                                                                          //
36 3 iztok
// Base time periods BTP_N = "5.0" and BTP_O = "1.0" are optimized for      //
37
// onewire timing. The default timing restricts the range of available      //
38
// frequences to multiples of 1MHz.                                         //
39
//                                                                          //
40 2 iztok
// If even this restrictions are too strict use timing BTP_N = "6.0" and    //
41
// BTP_O = "0.5", where the actual periods can be in the range:             //
42
// 6.0us <= BTP_N <= 7.5us                                                  //
43
// 0.5us <= BTP_O <= 0.66us                                                 //
44
//                                                                          //
45 3 iztok
// A third timing option is available for normal mode BTP_N = "7.5", this   //
46
// option is optimized for logic size.                                      //
47
//                                                                          //
48 2 iztok
//////////////////////////////////////////////////////////////////////////////
49
 
50
module sockit_owm #(
51 3 iztok
  // enable implementation of optional functionality
52
  parameter OVD_E =    1,  // overdrive functionality is implemented by default
53
  parameter CDR_E =    1,  // clock divider register is implemented by default
54 2 iztok
  // interface parameters
55
  parameter BDW   =   32,  // bus data width
56
  parameter OWN   =    1,  // number of 1-wire ports
57 3 iztok
  // computed bus address port width
58
`ifdef __ICARUS__
59
  parameter BAW   = (BDW==32) ? 1 : 2,
60
`else
61
  parameter BAW   = 1,  // TODO, the above is correct, but does not work well with Altera SOPC Builder
62
`endif
63 2 iztok
  // base time period
64 3 iztok
  parameter BTP_N = "5.0", // normal    mode (5.0us, options are "7.5", "5.0" and "6.0")
65 2 iztok
  parameter BTP_O = "1.0", // overdrive mode (1.0us, options are "1.0",       and "0.5")
66
  // normal mode timing
67 3 iztok
  parameter T_RSTH_N = (BTP_N == "7.5") ?  64 : (BTP_N == "5.0") ?  96 :  80,  // reset high
68
  parameter T_RSTL_N = (BTP_N == "7.5") ?  64 : (BTP_N == "5.0") ?  96 :  80,  // reset low
69
  parameter T_RSTP_N = (BTP_N == "7.5") ?  10 : (BTP_N == "5.0") ?  15 :  10,  // reset presence pulse
70
  parameter T_DAT0_N = (BTP_N == "7.5") ?   8 : (BTP_N == "5.0") ?  12 :  10,  // bit 0 low
71
  parameter T_DAT1_N = (BTP_N == "7.5") ?   1 : (BTP_N == "5.0") ?   1 :   1,  // bit 1 low
72
  parameter T_BITS_N = (BTP_N == "7.5") ?   2 : (BTP_N == "5.0") ?   3 :   2,  // bit sample
73
  parameter T_RCVR_N = (BTP_N == "7.5") ?   1 : (BTP_N == "5.0") ?   1 :   1,  // recovery
74
  parameter T_IDLE_N = (BTP_N == "7.5") ? 128 : (BTP_N == "5.0") ? 200 : 160,  // idle timer
75 2 iztok
  // overdrive mode timing
76 3 iztok
  parameter T_RSTH_O = (BTP_O == "1.0") ?  48 :  96,  // reset high
77
  parameter T_RSTL_O = (BTP_O == "1.0") ?  48 :  96,  // reset low
78
  parameter T_RSTP_O = (BTP_O == "1.0") ?  10 :  15,  // reset presence pulse
79
  parameter T_DAT0_O = (BTP_O == "1.0") ?   6 :  12,  // bit 0 low
80
  parameter T_DAT1_O = (BTP_O == "1.0") ?   1 :   2,  // bit 1 low
81
  parameter T_BITS_O = (BTP_O == "1.0") ?   2 :   3,  // bit sample
82
  parameter T_RCVR_O = (BTP_O == "1.0") ?   2 :   4,  // recovery
83
  parameter T_IDLE_O = (BTP_O == "1.0") ?  96 : 192,  // idle timer
84
  // clock divider ratios (defaults are for a 2MHz clock)
85
  parameter CDR_N = 5-1,  // normal    mode
86
  parameter CDR_O = 1-1   // overdrive mode
87 2 iztok
)(
88
  // system signals
89
  input            clk,
90
  input            rst,
91 3 iztok
  // CPU bus interface
92
  input            bus_ren,  // read  enable
93
  input            bus_wen,  // write enable
94
  input  [BAW-1:0] bus_adr,  // address
95
  input  [BDW-1:0] bus_wdt,  // write data
96
  output [BDW-1:0] bus_rdt,  // read  data
97
  output           bus_irq,  // interrupt request
98
  // 1-wire interface
99
  output [OWN-1:0] owr_p,    // output power enable
100
  output [OWN-1:0] owr_e,    // output pull down enable
101
  input  [OWN-1:0] owr_i     // input from bidirectional wire
102 2 iztok
);
103
 
104
//////////////////////////////////////////////////////////////////////////////
105
// local parameters
106
//////////////////////////////////////////////////////////////////////////////
107
 
108 3 iztok
// size of combined power and select registers
109
localparam PDW = (BDW==32) ? 24 : 8;
110
 
111 2 iztok
// size of boudrate generator counter (divider for normal mode is largest)
112 3 iztok
localparam CDW = CDR_E ? ((BDW==32) ? 16 : 8) : $clog2(CDR_N);
113 2 iztok
 
114
// size of port select signal
115
localparam SDW = $clog2(OWN);
116
 
117
// size of cycle timing counter
118
localparam TDW =       (T_RSTH_O+T_RSTL_O) >       (T_RSTH_N+T_RSTL_N)
119
               ? $clog2(T_RSTH_O+T_RSTL_O) : $clog2(T_RSTH_N+T_RSTL_N);
120
 
121
//////////////////////////////////////////////////////////////////////////////
122
// local signals
123
//////////////////////////////////////////////////////////////////////////////
124
 
125 3 iztok
// address dependent write enable
126
wire bus_ren_ctl_sts;
127
wire bus_wen_ctl_sts;
128
wire bus_wen_pwr_sel;
129
wire bus_wen_cdr_n;
130
wire bus_wen_cdr_o;
131
 
132
// read data bus segments
133
wire     [7:0] bus_rdt_ctl_sts;
134
wire [PDW-1:0] bus_rdt_pwr_sel;
135
 
136 2 iztok
// clock divider
137
reg  [CDW-1:0] div;
138 3 iztok
reg  [CDW-1:0] cdr_n;
139
reg  [CDW-1:0] cdr_o;
140 2 iztok
wire           pls;
141
 
142 3 iztok
// cycle control and status
143
reg            owr_cyc;  // cycle status
144
reg  [TDW-1:0] cnt;      // cycle counter
145 2 iztok
 
146
// port select
147
//generate if (OWN>1) begin : sel_declaration
148
reg  [SDW-1:0] owr_sel;
149
//end endgenerate
150
 
151 3 iztok
// modified input data for overdrive
152
wire           req_ovd;
153
 
154 2 iztok
// onewire signals
155
reg  [OWN-1:0] owr_pwr;  // power
156
reg            owr_ovd;  // overdrive
157
reg            owr_rst;  // reset
158 3 iztok
reg            owr_dat;  // data bit
159
reg            owr_smp;  // sample bit
160 2 iztok
 
161
reg            owr_oen;  // output enable
162 3 iztok
wire           owr_iln;  // input line
163 2 iztok
 
164
// interrupt signals
165 3 iztok
reg            irq_ena;  // interrupt enable
166
reg            irq_sts;  // interrupt status
167 2 iztok
 
168
// timing signals
169
wire [TDW-1:0] t_idl ;   // idle                 cycle    time
170
wire [TDW-1:0] t_rst ;   // reset                cycle    time
171 3 iztok
wire [TDW-1:0] t_bit ;   // data bit             cycle    time
172 2 iztok
wire [TDW-1:0] t_rstp;   // reset presence pulse sampling time
173
wire [TDW-1:0] t_rsth;   // reset                release  time
174
wire [TDW-1:0] t_dat0;   // data bit 0           release  time
175
wire [TDW-1:0] t_dat1;   // data bit 1           release  time
176 3 iztok
wire [TDW-1:0] t_bits;   // data bit             sampling time
177 2 iztok
wire [TDW-1:0] t_zero;   // end of               cycle    time
178
 
179
//////////////////////////////////////////////////////////////////////////////
180
// cycle timing
181
//////////////////////////////////////////////////////////////////////////////
182
 
183
// idle time
184 3 iztok
assign t_idl  = req_ovd ? T_IDLE_O                       : T_IDLE_N                      ;
185 2 iztok
// reset cycle time (reset low + reset hight)
186 3 iztok
assign t_rst  = req_ovd ? T_RSTL_O + T_RSTH_O            : T_RSTL_N + T_RSTH_N           ;
187
// data bit cycle time (write 0 + recovery)
188
assign t_bit  = req_ovd ? T_DAT0_O +          + T_RCVR_O : T_DAT0_N +            T_RCVR_N;
189 2 iztok
 
190
// reset presence pulse sampling time (reset high - reset presence)
191
assign t_rstp = owr_ovd ? T_RSTH_O - T_RSTP_O            : T_RSTH_N - T_RSTP_N           ;
192
// reset      release time (reset high)
193
assign t_rsth = owr_ovd ? T_RSTH_O                       : T_RSTH_N                      ;
194
 
195
// data bit 0 release time (write bit 0 - write bit 0 + recovery)
196
assign t_dat0 = owr_ovd ? T_DAT0_O - T_DAT0_O + T_RCVR_O : T_DAT0_N - T_DAT0_N + T_RCVR_N;
197
// data bit 1 release time (write bit 0 - write bit 1 + recovery)
198
assign t_dat1 = owr_ovd ? T_DAT0_O - T_DAT1_O + T_RCVR_O : T_DAT0_N - T_DAT1_N + T_RCVR_N;
199 3 iztok
// data bit sampling time (write bit 0 - write bit 1 + recovery)
200 2 iztok
assign t_bits = owr_ovd ? T_DAT0_O - T_BITS_O + T_RCVR_O : T_DAT0_N - T_BITS_N + T_RCVR_N;
201
 
202
// end of cycle time
203
assign t_zero = 'd0;
204
 
205
//////////////////////////////////////////////////////////////////////////////
206 3 iztok
// bus read
207 2 iztok
//////////////////////////////////////////////////////////////////////////////
208
 
209 3 iztok
// bus segnemt - controll/status register
210
assign bus_rdt_ctl_sts = {irq_ena, irq_sts, 1'b0, owr_pwr[0], owr_cyc, owr_ovd, owr_rst, owr_dat};
211
 
212
// bus segnemt - power and select register
213
generate
214
  if (BDW==32) begin
215
    if (OWN>1) begin
216
      assign bus_rdt_pwr_sel = {{16-OWN{1'b0}}, owr_pwr, 4'h0, {4-SDW{1'b0}}, owr_sel};
217
    end else begin
218
      assign bus_rdt_pwr_sel = 24'h0000_00;
219
    end
220
  end else if (BDW==8) begin
221
    if (OWN>1) begin
222
      assign bus_rdt_pwr_sel = {{ 4-OWN{1'b0}}, owr_pwr,       {4-SDW{1'b0}}, owr_sel};
223
    end else begin
224
      assign bus_rdt_pwr_sel = 8'hxx;
225
    end
226 2 iztok
  end
227 3 iztok
endgenerate
228
 
229
// bus read data
230
generate if (BDW==32) begin
231
  assign bus_rdt = (bus_adr[0]==1'b0) ? {bus_rdt_pwr_sel, bus_rdt_ctl_sts} : (cdr_o << 16 | cdr_n);
232
end else if (BDW==8) begin
233
  assign bus_rdt = (bus_adr[1]==1'b0) ? ((bus_adr[0]==1'b0) ? bus_rdt_ctl_sts
234
                                                            : bus_rdt_pwr_sel)
235
                                      : ((bus_adr[0]==1'b0) ? cdr_n
236
                                                            : cdr_o          );
237 2 iztok
end endgenerate
238
 
239
//////////////////////////////////////////////////////////////////////////////
240 3 iztok
// bus write
241 2 iztok
//////////////////////////////////////////////////////////////////////////////
242
 
243 3 iztok
// combined write/read enable and address decoder
244
generate if (BDW==32) begin
245
  assign bus_ren_ctl_sts = bus_ren & bus_adr[0] == 1'b0;
246
  assign bus_wen_ctl_sts = bus_wen & bus_adr[0] == 1'b0;
247
  assign bus_wen_pwr_sel = bus_wen & bus_adr[0] == 1'b0;
248
  assign bus_wen_cdr_n   = bus_wen & bus_adr[0] == 1'b1;
249
  assign bus_wen_cdr_o   = bus_wen & bus_adr[0] == 1'b1;
250
end else if (BDW==8) begin
251
  assign bus_ren_ctl_sts = bus_ren & bus_adr[1:0] == 2'b00;
252
  assign bus_wen_ctl_sts = bus_wen & bus_adr[1:0] == 2'b00;
253
  assign bus_wen_pwr_sel = bus_wen & bus_adr[1:0] == 2'b01;
254
  assign bus_wen_cdr_n   = bus_wen & bus_adr[1:0] == 2'b10;
255
  assign bus_wen_cdr_o   = bus_wen & bus_adr[1:0] == 2'b11;
256 2 iztok
end endgenerate
257
 
258 3 iztok
//////////////////////////////////////////////////////////////////////////////
259
// clock divider
260
//////////////////////////////////////////////////////////////////////////////
261
 
262
// clock divider ratio registers
263
generate
264
  if (CDR_E) begin
265
    if (BDW==32) begin
266
      always @ (posedge clk, posedge rst)
267
      if (rst) begin
268
        cdr_n <= CDR_N;
269
        cdr_o <= CDR_O;
270
      end else begin
271
        if (bus_wen_cdr_n)  cdr_n <= bus_wdt[15: 0];
272
        if (bus_wen_cdr_o)  cdr_o <= bus_wdt[31:16];
273
      end
274
    end else if (BDW==8) begin
275
      always @ (posedge clk, posedge rst)
276
      if (rst) begin
277
        cdr_n <= CDR_N;
278
        cdr_o <= CDR_O;
279
      end else begin
280
        if (bus_wen_cdr_n)  cdr_n <= bus_wdt;
281
        if (bus_wen_cdr_o)  cdr_o <= bus_wdt;
282
      end
283
    end
284
  end else begin
285
    initial begin
286
      cdr_n = CDR_N;
287
      cdr_o = CDR_O;
288
    end
289
  end
290
endgenerate
291
 
292
// clock divider
293
always @ (posedge clk, posedge rst)
294
if (rst)        div <= 'd0;
295
else begin
296
  if (bus_wen)  div <= 'd0;
297
  else          div <= pls ? 'd0 : div + owr_cyc;
298
end
299
 
300
// divided clock pulse
301
assign pls = (div == (owr_ovd ? cdr_o : cdr_n));
302
 
303
//////////////////////////////////////////////////////////////////////////////
304
// power and select register
305
//////////////////////////////////////////////////////////////////////////////
306
 
307
// select and power register implementation
308 2 iztok
generate if (OWN>1) begin : sel_implementation
309
  // port select
310
  always @ (posedge clk, posedge rst)
311 3 iztok
  if (rst)                   owr_sel <= {SDW{1'b0}};
312
  else if (bus_wen_pwr_sel)  owr_sel <= bus_wdt[(BDW==32 ?  8 : 0)+:SDW];
313
 
314 2 iztok
  // power delivery
315
  always @ (posedge clk, posedge rst)
316 3 iztok
  if (rst)                   owr_pwr <= {OWN{1'b0}};
317
  else if (bus_wen_pwr_sel)  owr_pwr <= bus_wdt[(BDW==32 ? 16 : 4)+:OWN];
318 2 iztok
end else begin
319
  // port select
320 3 iztok
  initial                    owr_sel <= 'd0;
321 2 iztok
  // power delivery
322
  always @ (posedge clk, posedge rst)
323 3 iztok
  if (rst)                   owr_pwr <= 1'b0;
324
  else if (bus_wen_ctl_sts)  owr_pwr <= bus_wdt[4];
325 2 iztok
end endgenerate
326
 
327 3 iztok
//////////////////////////////////////////////////////////////////////////////
328
// interrupt logic
329
//////////////////////////////////////////////////////////////////////////////
330
 
331 2 iztok
// bus interrupt
332 3 iztok
assign bus_irq = irq_ena & irq_sts;
333 2 iztok
 
334
// interrupt enable
335
always @ (posedge clk, posedge rst)
336 3 iztok
if (rst)                   irq_ena <= 1'b0;
337
else if (bus_wen_ctl_sts)  irq_ena <= bus_wdt[7];
338 2 iztok
 
339 3 iztok
// transmit status (active after onewire cycle ends)
340 2 iztok
always @ (posedge clk, posedge rst)
341 3 iztok
if (rst)                           irq_sts <= 1'b0;
342 2 iztok
else begin
343 3 iztok
  if (bus_wen_ctl_sts)             irq_sts <= 1'b0;
344
  else if (pls & (cnt == t_zero))  irq_sts <= 1'b1;
345
  else if (bus_ren_ctl_sts)        irq_sts <= 1'b0;
346 2 iztok
end
347
 
348
//////////////////////////////////////////////////////////////////////////////
349
// onewire state machine
350
//////////////////////////////////////////////////////////////////////////////
351
 
352 3 iztok
assign req_ovd = OVD_E ? bus_wen_ctl_sts & bus_wdt[2] : 1'b0;
353
 
354
// overdrive
355
always @ (posedge clk, posedge rst)
356
if (rst)                   owr_ovd <= 1'b0;
357
else if (bus_wen_ctl_sts)  owr_ovd <= req_ovd;
358
 
359
// reset
360
always @ (posedge clk, posedge rst)
361
if (rst)                   owr_rst <= 1'b0;
362
else if (bus_wen_ctl_sts)  owr_rst <= bus_wdt[1];
363
 
364 2 iztok
// transmit data, reset, overdrive
365 3 iztok
always @ (posedge clk, posedge rst)
366
if (rst)                           owr_dat <= 1'b0;
367
else begin
368
  if (bus_wen_ctl_sts)             owr_dat <= bus_wdt[0];
369
  else if (pls & (cnt == t_zero))  owr_dat <= owr_smp;
370
end
371 2 iztok
 
372 3 iztok
// onewire cycle status
373 2 iztok
always @ (posedge clk, posedge rst)
374 3 iztok
if (rst)                           owr_cyc <= 1'b0;
375 2 iztok
else begin
376 3 iztok
  if (bus_wen_ctl_sts)             owr_cyc <= bus_wdt[3] & ~&bus_wdt[2:0];
377
  else if (pls & (cnt == t_zero))  owr_cyc <= 1'b0;
378 2 iztok
end
379
 
380
// state counter (initial value depends whether the cycle is reset or data)
381
always @ (posedge clk, posedge rst)
382 5 iztok
if (rst)                 cnt <= 'd0;
383 2 iztok
else begin
384 3 iztok
  if (bus_wen_ctl_sts)   cnt <= (&bus_wdt[1:0] ? t_idl : bus_wdt[1] ? t_rst : t_bit) - 'd1;
385
  else if (pls)          cnt <= cnt - 'd1;
386 2 iztok
end
387
 
388
// receive data (sampling point depends whether the cycle is reset or data)
389
always @ (posedge clk)
390
if (pls) begin
391 3 iztok
  if      ( owr_rst & (cnt == t_rstp))  owr_smp <= owr_iln;  // presence detect
392
  else if (~owr_rst & (cnt == t_bits))  owr_smp <= owr_iln;  // read data bit
393 2 iztok
end
394
 
395
// output register (switch point depends whether the cycle is reset or data)
396
always @ (posedge clk, posedge rst)
397
if (rst)                                owr_oen <= 1'b0;
398
else begin
399 3 iztok
  if (bus_wen_ctl_sts)                  owr_oen <= ~&bus_wdt[1:0];
400 2 iztok
  else if (pls) begin
401
    if      (owr_rst & (cnt == t_rsth)) owr_oen <= 1'b0;  // reset
402 3 iztok
    else if (owr_dat & (cnt == t_dat1)) owr_oen <= 1'b0;  // write 1, read
403 2 iztok
    else if (          (cnt == t_dat0)) owr_oen <= 1'b0;  // write 0
404
  end
405
end
406
 
407
//////////////////////////////////////////////////////////////////////////////
408
// IO
409
//////////////////////////////////////////////////////////////////////////////
410
 
411
// only one 1-wire line cn be accessed at the same time
412 3 iztok
assign owr_e   = owr_oen << owr_sel;
413 2 iztok
// all 1-wire lines can be powered independently
414 3 iztok
assign owr_p   = owr_pwr;
415 2 iztok
 
416
// 1-wire line status read multiplexer
417 3 iztok
assign owr_iln = owr_i [owr_sel];
418 2 iztok
 
419
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.