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

Subversion Repositories altor32

[/] [altor32/] [trunk/] [rtl/] [cpu/] [altor32_fetch.v] - Blame information for rev 37

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 ultra_embe
//-----------------------------------------------------------------
2
//                           AltOR32 
3
//                Alternative Lightweight OpenRisc 
4 36 ultra_embe
//                            V2.1
5 27 ultra_embe
//                     Ultra-Embedded.com
6 36 ultra_embe
//                   Copyright 2011 - 2014
7 27 ultra_embe
//
8
//               Email: admin@ultra-embedded.com
9
//
10
//                       License: LGPL
11
//-----------------------------------------------------------------
12
//
13 37 ultra_embe
// Copyright (C) 2011 - 2014 Ultra-Embedded.com
14 27 ultra_embe
//
15
// This source file may be used and distributed without         
16
// restriction provided that this copyright statement is not    
17
// removed from the file and that any derivative work contains  
18
// the original copyright notice and the associated disclaimer. 
19
//
20
// This source file is free software; you can redistribute it   
21
// and/or modify it under the terms of the GNU Lesser General   
22
// Public License as published by the Free Software Foundation; 
23
// either version 2.1 of the License, or (at your option) any   
24
// later version.
25
//
26
// This source is distributed in the hope that it will be       
27
// useful, but WITHOUT ANY WARRANTY; without even the implied   
28
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
29
// PURPOSE.  See the GNU Lesser General Public License for more 
30
// details.
31
//
32
// You should have received a copy of the GNU Lesser General    
33
// Public License along with this source; if not, write to the 
34
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
35
// Boston, MA  02111-1307  USA
36
//-----------------------------------------------------------------
37
 
38
//-----------------------------------------------------------------
39
// Includes
40
//-----------------------------------------------------------------
41
`include "altor32_defs.v"
42
 
43
//-----------------------------------------------------------------
44
// Module - Instruction Fetch
45
//-----------------------------------------------------------------
46
module altor32_fetch
47
(
48
    // General
49
    input               clk_i /*verilator public*/,
50
    input               rst_i /*verilator public*/,
51
 
52
    // Instruction Fetch
53
    output              fetch_o /*verilator public*/,
54 36 ultra_embe
    output reg [31:0]   pc_o /*verilator public*/,
55 27 ultra_embe
    input [31:0]        data_i /*verilator public*/,
56
    input               data_valid_i/*verilator public*/,
57
 
58
    // Branch target
59
    input               branch_i /*verilator public*/,
60
    input [31:0]        branch_pc_i /*verilator public*/,
61
    input               stall_i /*verilator public*/,
62
 
63
    // Decoded opcode
64
    output [31:0]       opcode_o /*verilator public*/,
65
    output [31:0]       opcode_pc_o /*verilator public*/,
66
    output              opcode_valid_o /*verilator public*/,
67
 
68
    // Decoded register details
69
    output [4:0]        ra_o /*verilator public*/,
70
    output [4:0]        rb_o /*verilator public*/,
71
    output [4:0]        rd_o /*verilator public*/
72
);
73
 
74
//-----------------------------------------------------------------
75
// Params
76
//-----------------------------------------------------------------
77 37 ultra_embe
parameter   BOOT_VECTOR             = 32'h00000000;
78
parameter   CACHE_LINE_SIZE_WIDTH   = 5; /* 5-bits -> 32 entries */
79
parameter   PIPELINED_FETCH         = "DISABLED";
80 27 ultra_embe
 
81
//-----------------------------------------------------------------
82
// Registers
83
//-----------------------------------------------------------------
84 37 ultra_embe
reg         rd_q;
85
reg [31:0]  pc_q;
86
reg [31:0]  pc_last_q;
87 27 ultra_embe
 
88
//-------------------------------------------------------------------
89
// Next PC state machine
90
//-------------------------------------------------------------------
91 37 ultra_embe
wire [31:0] next_pc_w = pc_q + 32'd4;
92 27 ultra_embe
 
93
always @ (posedge clk_i or posedge rst_i)
94
begin
95
   if (rst_i)
96
   begin
97 37 ultra_embe
        pc_q        <= BOOT_VECTOR + `VECTOR_RESET;
98
        pc_last_q   <= BOOT_VECTOR + `VECTOR_RESET;
99
        rd_q        <= 1'b1;
100 27 ultra_embe
   end
101 36 ultra_embe
   else if (~stall_i)
102 27 ultra_embe
   begin
103
        // Branch - Next PC = branch target + 4
104
        if (branch_i)
105
        begin
106 37 ultra_embe
            rd_q        <= 1'b0;
107
            pc_last_q   <= pc_o;
108
            pc_q        <= branch_pc_i + 4;
109 27 ultra_embe
        end
110
        // Normal sequential execution (and instruction is ready)
111
        else if (data_valid_i)
112
        begin
113
            // New cache line?
114 37 ultra_embe
            if (next_pc_w[CACHE_LINE_SIZE_WIDTH-1:0] == {CACHE_LINE_SIZE_WIDTH{1'b0}})
115
                rd_q    <= 1'b1;
116
            else
117
                rd_q    <= 1'b0;
118 27 ultra_embe
 
119 37 ultra_embe
            pc_last_q   <= pc_o;
120
            pc_q        <= next_pc_w;
121 27 ultra_embe
        end
122 37 ultra_embe
        else
123
        begin
124
            rd_q        <= 1'b0;
125
            pc_last_q   <= pc_o;
126
        end
127 27 ultra_embe
   end
128
end
129
 
130
//-------------------------------------------------------------------
131 37 ultra_embe
// Instruction Fetch
132 27 ultra_embe
//-------------------------------------------------------------------
133 36 ultra_embe
always @ *
134 27 ultra_embe
begin
135 36 ultra_embe
    // Stall, revert to last requested PC
136
    if (stall_i)
137 37 ultra_embe
        pc_o    = pc_last_q;
138 36 ultra_embe
    else if (branch_i)
139 37 ultra_embe
        pc_o    = branch_pc_i;
140 36 ultra_embe
    else if (~data_valid_i)
141 37 ultra_embe
        pc_o    = pc_last_q;
142 36 ultra_embe
    else
143 37 ultra_embe
        pc_o    = pc_q;
144 27 ultra_embe
end
145
 
146 37 ultra_embe
assign fetch_o  = branch_i ? 1'b1 : rd_q;
147 36 ultra_embe
 
148 27 ultra_embe
//-------------------------------------------------------------------
149 36 ultra_embe
// Opcode output (retiming)
150 27 ultra_embe
//-------------------------------------------------------------------
151 36 ultra_embe
generate
152
if (PIPELINED_FETCH == "ENABLED")
153
begin: FETCH_FLOPS
154 37 ultra_embe
    reg [31:0] opcode_q;
155
    reg [31:0] opcode_pc_q;
156
    reg        opcode_valid_q;
157
    reg        branch_q;
158 27 ultra_embe
 
159 36 ultra_embe
    always @ (posedge clk_i or posedge rst_i)
160
    begin
161
       if (rst_i)
162
       begin
163 37 ultra_embe
            opcode_q        <= 32'b0;
164
            opcode_pc_q     <= 32'b0;
165
            opcode_valid_q  <= 1'b0;
166
            branch_q        <= 1'b0;
167 36 ultra_embe
       end
168
       else
169
       begin
170 37 ultra_embe
            branch_q        <= branch_i;
171 27 ultra_embe
 
172 36 ultra_embe
            if (~stall_i)
173
            begin
174 37 ultra_embe
                opcode_pc_q     <= pc_last_q;
175
                opcode_q        <= data_i;
176
                opcode_valid_q  <= (data_valid_i & !branch_i);
177 36 ultra_embe
            end
178
       end
179
    end
180
 
181
    // Opcode output
182 37 ultra_embe
    assign opcode_valid_o  = opcode_valid_q & ~branch_i & ~branch_q;
183
    assign opcode_o        = opcode_q;
184
    assign opcode_pc_o     = opcode_pc_q;
185 36 ultra_embe
end
186
//-------------------------------------------------------------------
187 27 ultra_embe
// Opcode output
188 36 ultra_embe
//-------------------------------------------------------------------
189
else
190
begin : NO_FETCH_FLOPS
191
    assign opcode_valid_o  = (data_valid_i & !branch_i);
192
    assign opcode_o        = data_i;
193 37 ultra_embe
    assign opcode_pc_o     = pc_last_q;
194 36 ultra_embe
end
195
endgenerate
196 27 ultra_embe
 
197 36 ultra_embe
//-------------------------------------------------------------------
198
// Opcode output
199
//-------------------------------------------------------------------
200 27 ultra_embe
// If simulation, RA = 03 if NOP instruction
201
`ifdef SIMULATION
202 37 ultra_embe
    wire [7:0] fetch_inst_w = {2'b00, opcode_o[31:26]};
203
    wire       nop_inst_w   = (fetch_inst_w == `INST_OR32_NOP);
204
    assign     ra_o         = nop_inst_w ? 5'd3 : opcode_o[20:16];
205 27 ultra_embe
`else
206
    assign     ra_o         = opcode_o[20:16];
207
`endif
208
 
209
assign rb_o            = opcode_o[15:11];
210
assign rd_o            = opcode_o[25:21];
211
 
212
endmodule

powered by: WebSVN 2.1.0

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