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

Subversion Repositories hive

[/] [hive/] [trunk/] [v04.05/] [pc_ring.v] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 ericw
/*
2
--------------------------------------------------------------------------------
3
 
4
Module : pc_ring.v
5
 
6
--------------------------------------------------------------------------------
7
 
8
Function:
9
- Processor PC storage ring.
10
 
11
Instantiates:
12
- (2x) pipe.v
13
 
14
Notes:
15
- 8 stages.
16
- Loop feedback, so PC interstage pipe registering forms a storage ring.
17
 
18
--------------------------------------------------------------------------------
19
*/
20
 
21
module pc_ring
22
        #(
23
        parameter       integer                                                 THREADS                 = 8,            // threads
24
        parameter       integer                                                 THRD_W                  = 3,            // thread width
25
        parameter       integer                                                 DATA_W                  = 32,           // data width
26
        parameter       integer                                                 ADDR_W                  = 16,           // address width
27
        parameter       [ADDR_W-1:0]                                     CLR_BASE                        = 'h0,  // clear address base (concat)
28
        parameter       integer                                                 CLR_SPAN                        = 2,            // clear address span (2^n)
29
        parameter       [ADDR_W-1:0]                                     INTR_BASE               = 'h20, // interrupt address base (concat)
30
        parameter       integer                                                 INTR_SPAN               = 2             // interrupt address span (2^n)
31
        )
32
        (
33
        // clocks & resets
34
        input                   wire                                                            clk_i,                                          // clock
35
        input                   wire                                                            rst_i,                                          // async. reset, active high
36
        // control I/O
37
        input                   wire    [THRD_W-1:0]                     thrd_0_i,                                       // thread
38
        input                   wire    [THRD_W-1:0]                     thrd_4_i,                                       // thread
39
        input                   wire                                                            clr_i,                                          // 1=pc clear
40
        input                   wire                                                            lit_i,                                          // 1 : pc=pc++ for literal data
41
        input                   wire                                                            jmp_i,                                          // 1 : pc=pc+B|I for jump (cond)
42
        input                   wire                                                            gto_i,                                          // 1 : pc=B for goto | gosub (cond)
43
        input                   wire                                                            intr_i,                                         // 1 : pc=int
44
        input                   wire                                                            res_tst_3_i,                            // 1=true (or disabled); 0=false
45
        // address I/O
46
        input                   wire    [ADDR_W-1:0]                     b_addr_i,                                       // b | im
47
        output          wire    [ADDR_W-1:0]                     pc_0_o,
48
        output          wire    [ADDR_W-1:0]                     pc_1_o,
49
        output          wire    [ADDR_W-1:0]                     pc_2_o,
50
        output          wire    [ADDR_W-1:0]                     pc_3_o,
51
        output          wire    [ADDR_W-1:0]                     pc_4_o,
52
        output          wire    [ADDR_W-1:0]                     pc_5_o,
53
        output          wire    [ADDR_W-1:0]                     pc_6_o,
54
        output          wire    [ADDR_W-1:0]                     pc_7_o
55
        );
56
 
57
 
58
        /*
59
        ----------------------
60
        -- internal signals --
61
        ----------------------
62
        */
63
        reg                                     [ADDR_W-1:0]                     pc[0:THREADS-1];
64
        //
65
        wire                                    [ADDR_W-1:0]                     clr_addr_0, intr_addr_4;
66
        wire                                                                                            intr_2, gto_2, jmp_2, lit_2;
67
        wire                                                                                            intr_3, gto_3, jmp_3;
68
        wire                                                                                            intr_4;
69
        wire    signed          [ADDR_W-1:0]                     b_addr_2, b_addr_3;
70
        reg                                     [ADDR_W-1:0]                     mux_0, mux_2, mux_3, mux_4;
71
 
72
 
73
        /*
74
        ================
75
        == code start ==
76
        ================
77
        */
78
 
79
        // form the clear address
80
        assign clr_addr_0[ADDR_W-1:THRD_W+CLR_SPAN] = CLR_BASE[ADDR_W-1:THRD_W+CLR_SPAN];
81
        assign clr_addr_0[THRD_W+CLR_SPAN-1:0] = thrd_0_i << CLR_SPAN;
82
 
83
        // mux for clear, next instruction
84
        always @ ( * ) begin
85
                casex ( { clr_i, intr_i } )
86
                        'b01    : mux_0 <= pc[0];  // no change for int
87
                        'b1x    : mux_0 <= clr_addr_0;  // clear
88
                        default : mux_0 <= pc[0] + 1'b1;  // inc for next
89
                endcase
90
        end
91
 
92
 
93
        // 0 to 2 regs
94
        pipe
95
        #(
96
        .DEPTH          ( 2 ),
97
        .WIDTH          ( 4+ADDR_W ),
98
        .RESET_VAL      ( 0 )
99
        )
100
        regs_0_2
101
        (
102
        .clk_i          ( clk_i ),
103
        .rst_i          ( rst_i ),
104
        .data_i         ( { lit_i, jmp_i, gto_i, intr_i, b_addr_i } ),
105
        .data_o         ( { lit_2, jmp_2, gto_2, intr_2, b_addr_2 } )
106
        );
107
 
108
 
109
        // mux for literal data
110
        always @ ( * ) begin
111
                casex ( lit_2 )
112
                        'b1     : mux_2 <= pc[2] + 1'b1;  // literal data
113
                        default : mux_2 <= pc[2];  // no change
114
                endcase
115
        end
116
 
117
 
118
        // 2 to 3 regs
119
        pipe
120
        #(
121
        .DEPTH          ( 1 ),
122
        .WIDTH          ( 3+ADDR_W ),
123
        .RESET_VAL      ( 0 )
124
        )
125
        regs_2_3
126
        (
127
        .clk_i          ( clk_i ),
128
        .rst_i          ( rst_i ),
129
        .data_i         ( { jmp_2, gto_2, intr_2, b_addr_2 } ),
130
        .data_o         ( { jmp_3, gto_3, intr_3, b_addr_3 } )
131
        );
132
 
133
 
134
        // mux for jmp, gto, gsb
135
        always @ ( * ) begin
136
                casex ( { res_tst_3_i, gto_3, jmp_3 } )
137
                        'b101   : mux_3 <= pc[3] + b_addr_3;  // jmp | jmp_i
138
                        'b11x   : mux_3 <= b_addr_3;  // gto | gsb
139
                        default : mux_3 <= pc[3];  // no change
140
                endcase
141
        end
142
 
143
 
144
        // 3 to 4 regs
145
        pipe
146
        #(
147
        .DEPTH          ( 1 ),
148
        .WIDTH          ( 1 ),
149
        .RESET_VAL      ( 0 )
150
        )
151
        regs_3_4
152
        (
153
        .clk_i          ( clk_i ),
154
        .rst_i          ( rst_i ),
155
        .data_i         ( intr_3 ),
156
        .data_o         ( intr_4 )
157
        );
158
 
159
 
160
        // form the interrupt address
161
        assign intr_addr_4[ADDR_W-1:THRD_W+INTR_SPAN] = INTR_BASE[ADDR_W-1:THRD_W+INTR_SPAN];
162
        assign intr_addr_4[THRD_W+INTR_SPAN-1:0] = thrd_4_i << INTR_SPAN;
163
 
164
        // mux for interrupt
165
        always @ ( * ) begin
166
                casex ( intr_4 )
167
                        'b1     : mux_4 <= intr_addr_4;  // interrupt
168
                        default : mux_4 <= pc[4];  // no change
169
                endcase
170
        end
171
 
172
        // pc storage ring
173
        integer j;
174
        always @ ( posedge clk_i or posedge rst_i ) begin
175
                if ( rst_i ) begin
176
                        for ( j = 0; j < THREADS; j = j + 1 ) begin
177
                                pc[j] <= 'b0;
178
                        end
179
                end else begin
180
                        for ( j = 0; j < THREADS; j = j + 1 ) begin
181
                                if ( j == 0 ) pc[j] <= pc[THREADS-1];  // wrap around
182
                                else if ( j == 1 ) pc[j] <= mux_0;
183
                                else if ( j == 3 ) pc[j] <= mux_2;
184
                                else if ( j == 4 ) pc[j] <= mux_3;
185
                                else if ( j == 5 ) pc[j] <= mux_4;
186
                                else pc[j] <= pc[j-1];
187
                        end
188
                end
189
        end
190
 
191
        // output pc
192
        assign pc_0_o = pc[0];
193
        assign pc_1_o = pc[1];
194
        assign pc_2_o = pc[2];
195
        assign pc_3_o = pc[3];
196
        assign pc_4_o = mux_4;  // note: async!
197
        assign pc_5_o = pc[5];
198
        assign pc_6_o = pc[6];
199
        assign pc_7_o = pc[7];
200
 
201
 
202
endmodule

powered by: WebSVN 2.1.0

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