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

Subversion Repositories hive

[/] [hive/] [trunk/] [v01.09/] [pc_ring.v] - Blame information for rev 8

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ericw
/*
2
--------------------------------------------------------------------------------
3
 
4
Module : pc_ring.v
5
 
6
--------------------------------------------------------------------------------
7
 
8
Function:
9
- Processor PC storage ring.
10
 
11
Instantiates:
12
- (2x) vector_sr.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                  = 2,            // thread width
25
        parameter       integer                                                 DATA_W                  = 32,           // data width
26
        parameter       integer                                                 ADDR_W                  = 16,           // address width
27
        parameter       integer                                                 IM_ADDR_W               = 5,            // immediate data width
28
        parameter       [ADDR_W-1:0]                                     CLR_BASE                        = 'h8,  // clear address base (concat)
29
        parameter       integer                                                 CLR_SPAN                        = 0,             // clear address span (2^n)
30
        parameter       [ADDR_W-1:0]                                     INTR_BASE               = 'h0,  // interrupt address base (concat)
31
        parameter       integer                                                 INTR_SPAN               = 0              // interrupt address span (2^n)
32
        )
33
        (
34
        // clocks & resets
35
        input                   wire                                                            clk_i,                                          // clock
36
        input                   wire                                                            rst_i,                                          // async. reset, active high
37
        // control I/O
38
        input                   wire    [THRD_W-1:0]                     thrd_0_i,                                       // thread
39
        input                   wire    [THRD_W-1:0]                     thrd_3_i,                                       // thread
40
        input                   wire                                                            clr_i,                                          // 1=pc clear
41
        input                   wire                                                            lit_i,                                          // 1 : pc=pc++ for lit
42
        input                   wire                                                            jmp_i,                                          // 1 : pc=pc+B for jump (cond)
43
        input                   wire                                                            gto_i,                                          // 1 : pc=B for goto / gosub (cond)
44
        input                   wire                                                            intr_i,                                         // 1 : pc=int
45
        input                   wire                                                            imad_i,                                         // 1=immediate address
46
        input                   wire                                                            tst_2_i,                                                // 1=true; 0=false
47
        // data I/O
48
        input                   wire    [DATA_W/2-1:0]                   b_lo_i,                                         // b_lo
49
        // address I/O
50
        input                   wire    [IM_ADDR_W-1:0]          im_addr_i,                                      // immediate address (offset)
51
        output          wire    [ADDR_W-1:0]                     pc_0_o,
52
        output          wire    [ADDR_W-1:0]                     pc_1_o,
53
        output          wire    [ADDR_W-1:0]                     pc_2_o,
54
        output          wire    [ADDR_W-1:0]                     pc_3_o,
55
        output          wire    [ADDR_W-1:0]                     pc_4_o,
56
        output          wire    [ADDR_W-1:0]                     pc_5_o,
57
        output          wire    [ADDR_W-1:0]                     pc_6_o,
58
        output          wire    [ADDR_W-1:0]                     pc_7_o
59
        );
60
 
61
 
62
        /*
63
        ----------------------
64
        -- internal signals --
65
        ----------------------
66
        */
67
        reg                                     [ADDR_W-1:0]                     pc[0:THREADS-1];
68
        //
69
        wire                                    [ADDR_W-1:0]                     clr_addr, intr_addr;
70
        wire                                                                                            intr_2, gto_2, jmp_2, lit_2;
71
        wire                                                                                            intr_3, gto_3;
72
        wire                                                                                            tst_3;
73
        wire    signed          [DATA_W/2-1:0]                   b_im, b_im_2, b_im_3;
74
        reg                                     [ADDR_W-1:0]                     pc_1_mux, pc_3_mux, pc_4_mux;
75
 
76
 
77
 
78
        /*
79
        ================
80
        == code start ==
81
        ================
82
        */
83
 
84
 
85
        // form the clear address
86
        assign clr_addr[ADDR_W-1:THRD_W+CLR_SPAN] = CLR_BASE[ADDR_W-1:THRD_W+CLR_SPAN];
87
        assign clr_addr[THRD_W+CLR_SPAN-1:0] = thrd_0_i << CLR_SPAN;
88
 
89
        // mux for clear, next
90
        always @ ( * ) begin
91
                casex ( { clr_i, intr_i } )
92
                        'b00 : pc_1_mux <= pc[0] + 1'b1;  // inc for next
93
                        'b01 : pc_1_mux <= pc[0];  // no change for int
94
                        'b1x : pc_1_mux <= clr_addr;  // clear
95
                endcase
96
        end
97
 
98
        // decode immediate offset
99
        assign b_im = ( imad_i ) ? $signed( im_addr_i ) : $signed( b_lo_i );
100
 
101
 
102
        // in to 2 regs
103
        vector_sr
104
        #(
105
        .REGS                   ( 2 ),
106
        .DATA_W         ( DATA_W/2+4 ),
107
        .RESET_VAL      ( 0 )
108
        )
109
        regs_in_2
110
        (
111
        .clk_i          ( clk_i ),
112
        .rst_i          ( rst_i ),
113
        .data_i         ( { b_im,   intr_i, gto_i, jmp_i, lit_i } ),
114
        .data_o         ( { b_im_2, intr_2, gto_2, jmp_2, lit_2 } )
115
        );
116
 
117
 
118
        // mux for lit, jump
119
        always @ ( * ) begin
120
                casex ( { jmp_2, lit_2 } )
121
                        3'b00 : pc_3_mux <= pc[2];  // no change
122
                        3'b01 : pc_3_mux <= pc[2] + 1'b1;  // inc for lit
123
                        3'b1x : pc_3_mux <= ( tst_2_i ) ? pc[2] + b_im_2 : pc[2];  // offset for jump
124
                endcase
125
        end
126
 
127
 
128
        // 2 to 3 regs
129
        vector_sr
130
        #(
131
        .REGS                   ( 1 ),
132
        .DATA_W         ( DATA_W/2+3 ),
133
        .RESET_VAL      ( 0 )
134
        )
135
        regs_2_3
136
        (
137
        .clk_i          ( clk_i ),
138
        .rst_i          ( rst_i ),
139
        .data_i         ( { b_im_2, intr_2, gto_2, tst_2_i } ),
140
        .data_o         ( { b_im_3, intr_3, gto_3, tst_3 } )
141
        );
142
 
143
 
144
        // form the interrupt address
145
        assign intr_addr[ADDR_W-1:THRD_W+INTR_SPAN] = INTR_BASE[ADDR_W-1:THRD_W+INTR_SPAN];
146
        assign intr_addr[THRD_W+INTR_SPAN-1:0] = thrd_3_i << INTR_SPAN;
147
 
148
        // mux for goto, gosub, interrupt
149
        always @ ( * ) begin
150
                casex ( { intr_3, gto_3 } )
151
                        'b00 : pc_4_mux <= pc[3];  // no change
152
                        'b01 : pc_4_mux <= ( tst_3 ) ? b_im_3 : pc[3];  // absolute goto / gosub
153
                        'b1x : pc_4_mux <= intr_addr;  // interrupt address
154
                endcase
155
        end
156
 
157
        // pc storage ring
158
        integer j;
159
        always @ ( posedge clk_i or posedge rst_i ) begin
160
                if ( rst_i ) begin
161
                        for ( j = 0; j < THREADS; j = j + 1 ) begin
162
                                pc[j] <= 'b0;
163
                        end
164
                end else begin
165
                        for ( j = 0; j < THREADS; j = j + 1 ) begin
166
                                if ( j == 0 ) pc[j] <= pc[THREADS-1];  // wrap around
167
                                else if ( j == 1 ) pc[j] <= pc_1_mux;
168
                                else if ( j == 3 ) pc[j] <= pc_3_mux;
169
                                else if ( j == 4 ) pc[j] <= pc_4_mux;
170
                                else pc[j] <= pc[j-1];
171
                        end
172
                end
173
        end
174
 
175
        // output pc
176
        assign pc_0_o = pc[0];
177
        assign pc_1_o = pc[1];
178
        assign pc_2_o = pc[2];
179
        assign pc_3_o = pc[3];
180
        assign pc_4_o = pc[4];
181
        assign pc_5_o = pc[5];
182
        assign pc_6_o = pc[6];
183
        assign pc_7_o = pc[7];
184
 
185
 
186
endmodule

powered by: WebSVN 2.1.0

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