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

Subversion Repositories scalable_arbiter

[/] [scalable_arbiter/] [trunk/] [rtl/] [verilog/] [stretcher.v] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 kendallc
/*
2
 * Copyright (c) 2008-2009, Kendall Correll
3
 *
4
 * Permission to use, copy, modify, and distribute this software for any
5
 * purpose with or without fee is hereby granted, provided that the above
6
 * copyright notice and this permission notice appear in all copies.
7
 *
8
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
 */
16
 
17
`timescale 1ns / 1ps
18
 
19
module stretcher #(
20
        parameter count = 1,
21
        parameter high_count = count,
22
        parameter low_count = count,
23
        parameter width = 1,
24
        parameter reset_value = {width{1'b0}}
25
)(
26
        input enable,
27
        input [width-1:0] in,
28
        output reg [width-1:0] out,
29
        output reg valid,
30
 
31
        input clock,
32
        input reset
33
);
34
 
35
`include "functions.v"
36
 
37
// edge detector
38
wire rising;
39
wire falling;
40
 
41
assign rising = |(~out & in);
42
assign falling = |(out & ~in);
43
 
44
/// counter width is the maximum size of the loaded value
45
parameter counter_width = max(flog2(count - 1) + 1,
46
        max(flog2(high_count - 1) + 1, flog2(low_count - 1) + 1));
47
 
48
reg [counter_width:0] counter;
49
reg [counter_width-1:0] counter_load;
50
wire counter_overflow;
51
 
52
assign counter_overflow = counter[counter_width];
53
 
54
// select counter value for rising or falling edge
55
always @(rising, falling)
56
begin
57
        case({rising, falling})
58
        'b11:
59
                counter_load = -count;
60
        'b10:
61
                counter_load = -high_count;
62
        'b01:
63
                counter_load = -low_count;
64
        default:
65
                counter_load = {counter_width{1'bx}};
66
        endcase
67
end
68
 
69
// the counter is reset on a rising or falling edge
70
// overflow has priority over reset, so input changes
71
// will be ignored until the full count is reached
72
always @(posedge clock, posedge reset)
73
begin
74
        if(reset)
75
                counter <= {counter_width{1'b0}};
76
        else
77
        begin
78
                if(enable & ~counter_overflow)
79
                        counter <= counter + 1;
80
                else if((rising | falling) & counter_overflow)
81
                        counter <= { 1'b0, counter_load };
82
        end
83
end
84
 
85
// output is gated by the counter overflow
86
always @(posedge clock, posedge reset)
87
begin
88
        if(reset)
89
                out <= reset_value;
90
        else
91
        begin
92
                if(counter_overflow)
93
                        out <= in;
94
        end
95
end
96
 
97
always @(posedge clock, posedge reset)
98
begin
99
        if(reset)
100
                valid <= 0;
101
        else
102
                valid <= counter_overflow;
103
end
104
 
105
endmodule

powered by: WebSVN 2.1.0

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