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

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [rtl/] [cpu/] [zap_predecode_coproc.v] - Blame information for rev 38

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

Line No. Rev Author Line
1 26 Revanth
// ----------------------------------------------------------------------------
2
//                            The ZAP Project
3
//                     (C)2016-2017, Revanth Kamaraj.     
4
// ----------------------------------------------------------------------------
5
// Filename     : zap_predecode_coproc.v
6
// HDL          : Verilog-2001
7
// Module       : zap_predecode_coproc       
8
// Author       : Revanth Kamaraj
9
// License      : GPL v2
10
// ----------------------------------------------------------------------------
11
//                               ABSTRACT
12
//                               --------
13
// Implements a simple coprocessor interface for the ZAP core. The interface
14
// is low bandwidth and thus is suited only for coprocessor that do not
15
// perform large data exchanges. Note that the translate function must be
16
// present in the coprocessor to account for CPU modes.
17
// ----------------------------------------------------------------------------
18
//                              INFORMATION                                  
19
//                              ------------
20
// Reset method : Synchronous active high reset
21
// Clock        : Core clock
22
// Depends      : --        
23
// ----------------------------------------------------------------------------
24
 
25
 
26
`default_nettype none
27
module zap_predecode_coproc #(
28
        parameter PHY_REGS = 46
29
)
30
(
31
        input wire              i_clk,
32
        input wire              i_reset,
33
 
34
        // Instruction and valid qualifier.
35
        input wire [34:0]       i_instruction,
36
        input wire              i_valid,
37
 
38
        // CPSR Thumb Bit.
39
        input wire              i_cpsr_ff_t,
40
        input wire [4:0]        i_cpsr_ff_mode,
41
 
42
        // Interrupts.
43
        input wire              i_irq,
44
        input wire              i_fiq,
45
 
46
         // Clear and stall signals.
47
        input wire              i_clear_from_writeback, // | High Priority
48
        input wire              i_data_stall,           // |
49
        input wire              i_clear_from_alu,       // |
50
        input wire              i_stall_from_shifter,   // |
51
        input wire              i_stall_from_issue,     // V Low Priority
52
 
53
        // Pipeline Valid. Must become 0 when every stage of the pipeline
54
        // is invalid.
55
        input wire              i_pipeline_dav,
56
 
57
        // Coprocessor done signal.
58
        input wire              i_copro_done,
59
 
60
        // Interrupts output.
61
        output reg              o_irq,
62
        output reg              o_fiq,
63
 
64
        // Instruction and valid qualifier.
65
        output reg [34:0]       o_instruction,
66
        output reg              o_valid,
67
 
68
        // We can generate stall if coprocessor is slow. We also have
69
        // some minimal latency.
70
        output reg              o_stall_from_decode,
71
 
72
        // Are we really asking for the coprocessor ?
73
        output reg              o_copro_dav_ff,
74
 
75
        // The entire instruction is passed to the coprocessor.
76
        output reg  [31:0]      o_copro_word_ff
77
);
78
 
79
///////////////////////////////////////////////////////////////////////////////
80
 
81
`include "zap_defines.vh"
82
`include "zap_localparams.vh"
83
`include "zap_functions.vh"
84
 
85
///////////////////////////////////////////////////////////////////////////////
86
 
87
localparam IDLE = 0;
88
localparam BUSY = 1;
89
 
90
///////////////////////////////////////////////////////////////////////////////
91
 
92
// State register.
93
reg state_ff, state_nxt;
94
 
95
// Output registers.
96
reg        cp_dav_ff, cp_dav_nxt;
97
reg [31:0] cp_word_ff, cp_word_nxt;
98
 
99
///////////////////////////////////////////////////////////////////////////////
100
 
101
// Connect output registers to output.
102
always @*
103
begin
104
        o_copro_word_ff = cp_word_ff;
105
        o_copro_dav_ff  = cp_dav_ff;
106
end
107
 
108
///////////////////////////////////////////////////////////////////////////////
109
 
110
wire c1 = !i_cpsr_ff_t;
111
wire c2 = i_cpsr_ff_mode != USR;
112
wire c3 = i_instruction[11:8] == 4'b1111;
113
wire c4 = i_instruction[34:32] == 3'd0;
114
wire c5 = c1 & c2 & c3 & c4;
115
 
116 38 Revanth
`ifndef SYNTHESIS
117
 
118
reg eclass;
119
 
120
`endif
121
 
122 26 Revanth
// Next state logic.
123
always @*
124
begin
125
        // Default values.
126
        cp_dav_nxt              = cp_dav_ff;
127
        cp_word_nxt             = cp_word_ff;
128
        o_stall_from_decode     = 1'd0;
129
        o_instruction           = i_instruction;
130
        o_valid                 = i_valid;
131
        state_nxt               = state_ff;
132
        o_irq                   = i_irq;
133
        o_fiq                   = i_fiq;
134
 
135 38 Revanth
        `ifndef SYNTHESIS
136
                eclass = 0;
137
        `endif
138
 
139 26 Revanth
        case ( state_ff )
140
        IDLE:
141
                // Activate only if no thumb, not in USER mode and CP15 access is requested.
142 38 Revanth
                casez ( (!i_cpsr_ff_t && (i_instruction[34:32] == 3'd0) && i_valid) ? i_instruction[31:0] : 35'd0 )
143 26 Revanth
                MRC, MCR, LDC, STC, CDP:
144
                begin
145 38 Revanth
                        if ( i_instruction[11:8] == 4'b1111 && i_cpsr_ff_mode != USR )  // CP15 and root access -- perfectly fine.
146
                        begin
147
                                // Send ANDNV R0, R0, R0 instruction.
148
                                o_instruction = {4'b1111, 28'd0};
149
                                o_valid       = 1'd0;
150
                                o_irq         = 1'd0;
151
                                o_fiq         = 1'd0;
152 26 Revanth
 
153 38 Revanth
                                // As long as there is an instruction to process...
154
                                if ( i_pipeline_dav )
155
                                begin
156
                                        // Do not impose any output. However, continue
157
                                        // to stall all before this unit in the 
158
                                        // pipeline.
159
                                        o_valid                 = 1'd0;
160
                                        o_stall_from_decode     = 1'd1;
161
                                        cp_dav_nxt              = 1'd0;
162
                                        cp_word_nxt             = 32'd0;
163
                                end
164
                                else
165
                                begin
166
                                        // Prepare to move to BUSY. Continue holding
167
                                        // stall. Send out 0s.
168
                                        o_valid                 = 1'd0;
169
                                        o_stall_from_decode     = 1'd1;
170
                                        cp_word_nxt             = i_instruction;
171
                                        cp_dav_nxt              = 1'd1;
172
                                        state_nxt               = BUSY;
173
                                end
174 26 Revanth
                        end
175 38 Revanth
                        else // Warning...
176 26 Revanth
                        begin
177 38 Revanth
                                `ifndef SYNTHESIS
178
 
179
                                if ( i_instruction[11:8] != 4'b1111 )
180
                                        eclass = 1;
181
                                else
182
                                        eclass = 2;
183
 
184
                                `endif
185
 
186
                                // Remain transparent since this is not a coprocessor
187
                                // instruction.
188
                                o_valid                 = i_valid;
189
                                o_instruction           = i_instruction;
190
                                o_irq                   = i_irq;
191
                                o_fiq                   = i_fiq;
192
                                cp_dav_nxt              = 0;
193
                                o_stall_from_decode     = 0;
194
                                cp_word_nxt             = {32{1'dx}}; // Don't care.
195 26 Revanth
                        end
196
                end
197
                default:
198
                begin
199
                        // Remain transparent since this is not a coprocessor
200
                        // instruction.
201
                        o_valid                 = i_valid;
202
                        o_instruction           = i_instruction;
203
                        o_irq                   = i_irq;
204
                        o_fiq                   = i_fiq;
205
                        cp_dav_nxt              = 0;
206
                        o_stall_from_decode     = 0;
207
                        cp_word_nxt             = {32{1'dx}}; // Don't care.
208
                end
209
                endcase
210
 
211
        BUSY:
212
        begin
213
                // Provide coprocessor word and valid to the coprocessor.
214
                cp_word_nxt             = cp_word_ff;
215
                cp_dav_nxt              = cp_dav_ff;
216
 
217
                // Continue holding stall.
218
                o_stall_from_decode     = 1'd1;
219
 
220
                // Send out nothing.
221
                o_valid                 = 1'd0;
222
                o_instruction           = 32'd0;
223
 
224
                // Block interrupts.
225
                o_irq = 1'd0;
226
                o_fiq = 1'd0;
227
 
228
                // If we get a response, we can move back to IDLE. Release
229
                // the stall so that processor can continue.
230
                if ( i_copro_done )
231
                begin
232
                        cp_dav_nxt              = 1'd0;
233
                        cp_word_nxt             = 32'd0;
234
                        state_nxt               = IDLE;
235
                        o_stall_from_decode     = 1'd0;
236
                end
237
        end
238
        endcase
239
end
240
 
241
always @ (posedge i_clk)
242
begin
243
        if ( i_reset )
244
        begin
245
                clear;
246
        end
247
        else if ( i_clear_from_writeback )
248
        begin
249
                clear;
250
        end
251
        else if ( i_data_stall )
252
        begin
253
                // Preserve values.
254
        end
255
        else if ( i_clear_from_alu )
256
        begin
257
                clear;
258
        end
259
        else if ( i_stall_from_shifter )
260
        begin
261
                // Preserve values.
262
        end
263
        else if ( i_stall_from_issue )
264
        begin
265
                // Preserve values.
266
        end
267
        else
268
        begin
269
                state_ff   <= state_nxt;
270
                cp_word_ff <= cp_word_nxt;
271
                cp_dav_ff  <= cp_dav_nxt;
272
        end
273
end
274
 
275
// Clear out the unit.
276
task clear;
277
begin
278
                state_ff            <= IDLE;
279
                cp_dav_ff           <= 1'd0;
280
end
281
endtask
282
 
283
endmodule
284
`default_nettype wire

powered by: WebSVN 2.1.0

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