OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [rtl/] [src_peripheral/] [timer/] [timer.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
 
2
/**********************************************************************
3
**      File:  timer.v
4
**
5
**
6
**      Copyright (C) 2014-2017  Alireza Monemi
7
**
8
**      This file is part of ProNoC
9
**
10
**      ProNoC ( stands for Prototype Network-on-chip)  is free software:
11
**      you can redistribute it and/or modify it under the terms of the GNU
12
**      Lesser General Public License as published by the Free Software Foundation,
13
**      either version 2 of the License, or (at your option) any later version.
14
**
15
**      ProNoC is distributed in the hope that it will be useful, but WITHOUT
16
**      ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17
**      or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
18
**      Public License for more details.
19
**
20
**      You should have received a copy of the GNU Lesser General Public
21
**      License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
22
**
23
**
24
**      Description:
25
**      A simple, general purpose, Wishbone bus-based, 32-bit timer
26
**
27
**
28
*******************************************************************/
29
 
30
 
31
// synthesis translate_off
32
`timescale 1ns / 1ps
33
// synthesis translate_on
34
 
35
 
36
module timer #(
37
                parameter PRESCALER_WIDTH               =       8, // Prescaler counter width.
38
                parameter Dw  = 32,   // wishbone bus data width
39
                parameter Aw  = 3,     // wishbone bus address width
40
                parameter SELw= 4,    // wishbone bus sel width
41
                parameter TAGw=3,
42
                parameter CNTw=32     // timer width
43
 
44
 
45
)(
46
    clk,
47
    reset,
48
 
49
    //wishbone bus interface
50
    sa_dat_i,
51
    sa_sel_i,
52
    sa_addr_i,
53
    sa_tag_i,
54
    sa_stb_i,
55
    sa_cyc_i,
56
    sa_we_i,
57
    sa_dat_o,
58
    sa_ack_o,
59
    sa_err_o,
60
    sa_rty_o,
61
 
62
 
63
        //intruupt interface
64
        irq
65
);
66
 
67
    function integer log2;
68
      input integer number; begin
69
         log2=0;
70
         while(2**log2<number) begin
71
            log2=log2+1;
72
         end
73
      end
74
   endfunction // log2 
75
 
76
 
77
    input                       clk;
78
    input                       reset;
79
 
80
    //wishbone bus interface
81
    input       [Dw-1       :   0]      sa_dat_i;
82
    input       [SELw-1     :   0]      sa_sel_i;
83
    input       [Aw-1       :   0]      sa_addr_i;
84
    input       [TAGw-1     :   0]      sa_tag_i;
85
    input                               sa_stb_i;
86
    input                               sa_cyc_i;
87
    input                               sa_we_i;
88
 
89
    output      [Dw-1       :   0]      sa_dat_o;
90
    output  reg                         sa_ack_o;
91
    output                              sa_err_o;
92
    output                              sa_rty_o;
93
 
94
 
95
    assign  sa_err_o=1'b0;
96
    assign  sa_rty_o=1'b0;
97
    //intruupt interface
98
    output                      irq;
99
 
100
 
101
 
102
    localparam TCSR_ADDR        =       0;       //timer control register
103
    localparam TLR_ADDR         =       1;      //timer load register
104
    localparam TCMR_ADDR        =       2;// timer compare value register
105
 
106
 
107
 
108
    localparam  DEV_CTRL_WIDTH  =       log2(PRESCALER_WIDTH);
109
 
110
    localparam TCSR_REG_WIDTH   =       4+DEV_CTRL_WIDTH;
111
    localparam TCR_REG_WIDTH    =       TCSR_REG_WIDTH-1;
112
/***************************
113
tcr: timer control register
114
bit
115
 
116
PRESCALER_WIDTH+3: 4:   prescaler_ctrl
117
3       :       timer_isr
118
2       :       rst_on_cmp_value
119
1       :       int_enble_on_cmp_value
120
 
121
 
122
 
123
 
124
 
125
***************************/
126
    reg         [TCSR_REG_WIDTH-1               :       0]       tcsr;
127
    wire        [TCSR_REG_WIDTH-1               :       0]       tcsr_next;      //timer control register 
128
    reg [TCR_REG_WIDTH-1                :       0]       tcr_next;
129
    reg timer_isr_next;
130
 
131
    reg         [PRESCALER_WIDTH-1      :       0]       prescaler_counter,prescaler_counter_next;
132
 
133
    wire        [PRESCALER_WIDTH-1      :       0]       dev_one_hot;
134
    wire        [PRESCALER_WIDTH-2      :       0]       dev_cmp_val;
135
 
136
    wire timer_en,int_en,rst_on_cmp,timer_isr;
137
    wire prescaler_rst,counter_rst;
138
    wire [DEV_CTRL_WIDTH-1      :       0] prescaler_ctrl;
139
 
140
 
141
 
142
    reg [CNTw-1         :       0]       counter,counter_next,cmp,cmp_next,read,read_next;
143
 
144
 
145
 
146
    assign {timer_isr,prescaler_ctrl,rst_on_cmp,int_en,timer_en} = tcsr;
147
    assign dev_cmp_val  =       dev_one_hot[PRESCALER_WIDTH-1   :       1];
148
    assign prescaler_rst        =       prescaler_counter [PRESCALER_WIDTH-2 :   0]      ==      dev_cmp_val;
149
    assign counter_rst  =       (rst_on_cmp)? (counter          ==      cmp) : 1'b0;
150
    assign sa_dat_o             =       read;
151
    assign irq = timer_isr;
152
    assign tcsr_next            ={timer_isr_next,tcr_next};
153
 
154
 
155
    bin_to_one_hot #(
156
           .BIN_WIDTH           (DEV_CTRL_WIDTH),
157
           .ONE_HOT_WIDTH       (PRESCALER_WIDTH)
158
        )
159
        conv
160
        (
161
           .bin_code            (prescaler_ctrl),
162
           .one_hot_code        (dev_one_hot)
163
        );
164
 
165
 `ifdef SYNC_RESET_MODE
166
    always @ (posedge clk )begin
167
`else
168
    always @ (posedge clk or posedge reset)begin
169
`endif
170
                if(reset) begin
171
                        counter                         <= {CNTw{1'b0}};
172
                        cmp                                     <=      {CNTw{1'b1}};
173
                        prescaler_counter       <=      {PRESCALER_WIDTH{1'b0}};
174
                        tcsr                                    <=      {TCSR_REG_WIDTH{1'b0}};
175
                        read                                    <=      {CNTw{1'b0}};
176
                        sa_ack_o                                <=      1'b0;
177
                end else begin
178
                        counter                         <= counter_next;
179
                        cmp                                     <=      cmp_next;
180
                        prescaler_counter       <=      prescaler_counter_next;
181
                        tcsr                                    <=      tcsr_next;
182
                        read                                    <= read_next;
183
                        sa_ack_o                                <= sa_stb_i && ~sa_ack_o;
184
                end
185
        end
186
 
187
        always@(*)begin
188
                counter_next                    = counter;
189
                prescaler_counter_next  = prescaler_counter;
190
                timer_isr_next                  =(timer_isr | (counter_rst & prescaler_rst) ) &  int_en;
191
                tcr_next                                        = tcsr[TCR_REG_WIDTH-1          :       0];
192
                cmp_next                                        = cmp;
193
                read_next                               =       read;
194
                //counters
195
                if(timer_en)begin
196
                                if(prescaler_rst)       begin
197
                                        prescaler_counter_next  =       {PRESCALER_WIDTH{1'b0}};
198
                                        if(counter_rst) begin
199
                                                counter_next    =       {CNTw{1'b0}};
200
                                        end else begin
201
                                                counter_next    =       counter +1'b1;
202
                                        end // count_rst
203
                                end else begin
204
                                                prescaler_counter_next  =       prescaler_counter       +1'b1;
205
                                end //dev_rst
206
                end//time_en
207
 
208
                if(sa_stb_i )begin
209
                        if(sa_we_i ) begin
210
                                case(sa_addr_i)
211
                                        TCSR_ADDR:      begin
212
                                                tcr_next                =       sa_dat_i[TCR_REG_WIDTH-1        :       0];
213
                                                timer_isr_next  =       timer_isr & ~sa_dat_i[TCSR_REG_WIDTH-1];// reset isr by writting 1
214
                                        end
215
                                        TLR_ADDR:       counter_next    =       sa_dat_i[CNTw-1 :       0];
216
                                        TCMR_ADDR:      cmp_next                        =       sa_dat_i[CNTw-1 :       0];
217
                                        default:                        cmp_next                        =       cmp;
218
                                endcase
219
                        end//we
220
                        else begin
221
                                case(sa_addr_i)
222
                                        TCSR_ADDR:      read_next               =       {{(Dw-TCSR_REG_WIDTH){1'b0}},tcsr};
223
                                        TLR_ADDR:       read_next               =       counter;
224
                                        TCMR_ADDR:      read_next               =       cmp;
225
                                        default:                        read_next               =       read;
226
                                endcase
227
                        end
228
                end//stb
229
        end//always
230
 
231
 
232
 
233
endmodule

powered by: WebSVN 2.1.0

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