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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [rtl/] [zipbones.v] - Blame information for rev 209

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 201 dgisselq
////////////////////////////////////////////////////////////////////////////////
2 38 dgisselq
//
3
// Filename:    zipbones.v
4
//
5
// Project:     Zip CPU -- a small, lightweight, RISC CPU soft core
6
//
7
// Purpose:     In the spirit of keeping the Zip CPU small, this implements a
8
//              Zip System with no peripherals: Any peripherals you wish will
9
//              need to be implemented off-module.
10
//
11
// Creator:     Dan Gisselquist, Ph.D.
12 69 dgisselq
//              Gisselquist Technology, LLC
13 38 dgisselq
//
14 201 dgisselq
////////////////////////////////////////////////////////////////////////////////
15 38 dgisselq
//
16 209 dgisselq
// Copyright (C) 2015-2019, Gisselquist Technology, LLC
17 38 dgisselq
//
18
// This program is free software (firmware): you can redistribute it and/or
19
// modify it under the terms of  the GNU General Public License as published
20
// by the Free Software Foundation, either version 3 of the License, or (at
21
// your option) any later version.
22
//
23
// This program is distributed in the hope that it will be useful, but WITHOUT
24
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
25
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
26
// for more details.
27
//
28 201 dgisselq
// You should have received a copy of the GNU General Public License along
29 209 dgisselq
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
30 201 dgisselq
// target there if the PDF file isn't present.)  If not, see
31
// <http://www.gnu.org/licenses/> for a copy.
32
//
33 38 dgisselq
// License:     GPL, v3, as defined and found on www.gnu.org,
34
//              http://www.gnu.org/licenses/gpl.html
35
//
36
//
37 201 dgisselq
////////////////////////////////////////////////////////////////////////////////
38 38 dgisselq
//
39 201 dgisselq
//
40 209 dgisselq
`default_nettype        none
41
//
42 105 dgisselq
`include "cpudefs.v"
43
//
44 209 dgisselq
`define RESET_BIT       6
45
`define STEP_BIT        8
46
`define HALT_BIT        10
47
`define CLEAR_CACHE_BIT 11
48
//
49
module  zipbones(i_clk, i_reset,
50 38 dgisselq
                // Wishbone master interface from the CPU
51 201 dgisselq
                o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
52 38 dgisselq
                        i_wb_ack, i_wb_stall, i_wb_data, i_wb_err,
53
                // Incoming interrupts
54
                i_ext_int,
55
                // Our one outgoing interrupt
56
                o_ext_int,
57
                // Wishbone slave interface for debugging purposes
58
                i_dbg_cyc, i_dbg_stb, i_dbg_we, i_dbg_addr, i_dbg_data,
59 66 dgisselq
                        o_dbg_ack, o_dbg_stall, o_dbg_data
60
`ifdef  DEBUG_SCOPE
61 209 dgisselq
                , o_cpu_debug
62 66 dgisselq
`endif
63
                );
64 201 dgisselq
        parameter       RESET_ADDRESS=32'h0100000, ADDRESS_WIDTH=30,
65 209 dgisselq
                        LGICACHE=8;
66
        parameter [0:0]   START_HALTED=0;
67
        parameter       EXTERNAL_INTERRUPTS=1,
68
`ifdef  OPT_MULTIPLY
69
                        IMPLEMENT_MPY = `OPT_MULTIPLY;
70
`else
71
                        IMPLEMENT_MPY = 0;
72
`endif
73
        parameter [0:0]
74
`ifdef  OPT_DIVIDE
75
                        IMPLEMENT_DIVIDE=1,
76
`else
77
                        IMPLEMENT_DIVIDE=0,
78
`endif
79
`ifdef  OPT_IMPLEMENT_FPU
80
                        IMPLEMENT_FPU=1,
81
`else
82
                        IMPLEMENT_FPU=0,
83
`endif
84
                        IMPLEMENT_LOCK=1;
85
        localparam      // Derived parameters
86
                        PHYSICAL_ADDRESS_WIDTH=ADDRESS_WIDTH,
87
                        PAW=ADDRESS_WIDTH,
88
`ifdef  OPT_MMU
89
                        VIRTUAL_ADDRESS_WIDTH=30,
90
`else
91
                        VIRTUAL_ADDRESS_WIDTH=PAW,
92
`endif
93
                        LGTLBSZ = 6,
94
                        VAW=VIRTUAL_ADDRESS_WIDTH;
95
 
96 201 dgisselq
        localparam      AW=ADDRESS_WIDTH;
97 209 dgisselq
        input   wire    i_clk, i_reset;
98 38 dgisselq
        // Wishbone master
99
        output  wire            o_wb_cyc, o_wb_stb, o_wb_we;
100 209 dgisselq
        output  wire    [(PAW-1):0]      o_wb_addr;
101 38 dgisselq
        output  wire    [31:0]   o_wb_data;
102 201 dgisselq
        output  wire    [3:0]    o_wb_sel;
103 209 dgisselq
        input   wire            i_wb_ack, i_wb_stall;
104
        input   wire    [31:0]   i_wb_data;
105
        input   wire            i_wb_err;
106 38 dgisselq
        // Incoming interrupts
107 209 dgisselq
        input   wire            i_ext_int;
108 38 dgisselq
        // Outgoing interrupt
109
        output  wire            o_ext_int;
110
        // Wishbone slave
111 209 dgisselq
        input   wire            i_dbg_cyc, i_dbg_stb, i_dbg_we, i_dbg_addr;
112
        input   wire    [31:0]   i_dbg_data;
113
        output  wire            o_dbg_ack;
114 38 dgisselq
        output  wire            o_dbg_stall;
115
        output  wire    [31:0]   o_dbg_data;
116 56 dgisselq
        //
117 66 dgisselq
`ifdef  DEBUG_SCOPE
118 209 dgisselq
        output  wire    [31:0]   o_cpu_debug;
119 66 dgisselq
`endif
120 209 dgisselq
        wire            dbg_cyc, dbg_stb, dbg_we, dbg_addr, dbg_stall;
121
        wire    [31:0]   dbg_idata, dbg_odata;
122
        reg             dbg_ack;
123 38 dgisselq
 
124 209 dgisselq
        assign  dbg_cyc     = i_dbg_cyc;
125
        assign  dbg_stb     = i_dbg_stb;
126
        assign  dbg_we      = i_dbg_we;
127
        assign  dbg_addr    = i_dbg_addr;
128
        assign  dbg_idata   = i_dbg_data;
129
        assign  o_dbg_ack   = dbg_ack;
130
        assign  o_dbg_stall = dbg_stall;
131
        assign  o_dbg_data  = dbg_odata;
132 38 dgisselq
        //
133
        // The external debug interface
134
        //
135
        // We offer only a limited interface here, requiring a pre-register
136
        // write to set the local address.  This interface allows access to
137
        // the Zip System on a debug basis only, and not to the rest of the
138
        // wishbone bus.  Further, to access these registers, the control
139
        // register must first be accessed to both stop the CPU and to 
140
        // set the following address in question.  Hence all accesses require
141
        // two accesses: write the address to the control register (and halt
142
        // the CPU if not halted), then read/write the data from the data
143
        // register.
144
        //
145
        wire            cpu_break, dbg_cmd_write;
146
        reg             cmd_reset, cmd_halt, cmd_step, cmd_clear_pf_cache;
147
        reg     [4:0]    cmd_addr;
148 56 dgisselq
        wire    [3:0]    cpu_dbg_cc;
149 209 dgisselq
        assign  dbg_cmd_write = (dbg_stb)&&(dbg_we)&&(!dbg_addr);
150 38 dgisselq
        //
151 91 dgisselq
        // Always start us off with an initial reset
152
        //
153 38 dgisselq
        initial cmd_reset = 1'b1;
154
        always @(posedge i_clk)
155 209 dgisselq
                cmd_reset <= ((dbg_cmd_write)&&(dbg_idata[`RESET_BIT]));
156 38 dgisselq
        //
157 69 dgisselq
        initial cmd_halt  = START_HALTED;
158 38 dgisselq
        always @(posedge i_clk)
159 209 dgisselq
        if (i_reset)
160
                cmd_halt <= START_HALTED;
161
        else if (cmd_reset)
162
                cmd_halt <= START_HALTED;
163
        else if (dbg_cmd_write)
164
                cmd_halt <= ((dbg_idata[`HALT_BIT])&&(!dbg_idata[`STEP_BIT]));
165
        else if ((cmd_step)||(cpu_break))
166
                cmd_halt  <= 1'b1;
167 38 dgisselq
 
168 209 dgisselq
        initial cmd_clear_pf_cache = 1'b1;
169 38 dgisselq
        always @(posedge i_clk)
170 209 dgisselq
                cmd_clear_pf_cache <= (dbg_cmd_write)&&(dbg_idata[`CLEAR_CACHE_BIT]);
171 38 dgisselq
        //
172
        initial cmd_step  = 1'b0;
173
        always @(posedge i_clk)
174 209 dgisselq
                cmd_step <= (dbg_cmd_write)&&(dbg_idata[`STEP_BIT]);
175 38 dgisselq
        //
176 91 dgisselq
        initial cmd_addr = 5'h0;
177 38 dgisselq
        always @(posedge i_clk)
178
                if (dbg_cmd_write)
179 209 dgisselq
                        cmd_addr <= dbg_idata[4:0];
180 38 dgisselq
 
181
        wire    cpu_reset;
182 209 dgisselq
        assign  cpu_reset = (cmd_reset);
183 38 dgisselq
 
184
        wire    cpu_halt, cpu_dbg_stall;
185 209 dgisselq
        assign  cpu_halt = (cmd_halt);
186 38 dgisselq
        wire    [31:0]   cmd_data;
187
        // Values:
188
        //      0x0003f -> cmd_addr mask
189
        //      0x00040 -> reset
190 209 dgisselq
        //      0x00080 -> PIC interrrupt pending
191 38 dgisselq
        //      0x00100 -> cmd_step
192
        //      0x00200 -> cmd_stall
193
        //      0x00400 -> cmd_halt
194
        //      0x00800 -> cmd_clear_pf_cache
195
        //      0x01000 -> cc.sleep
196
        //      0x02000 -> cc.gie
197
        //      0x10000 -> External interrupt line is high
198 48 dgisselq
        assign  cmd_data = { 7'h00, 8'h00, i_ext_int,
199 56 dgisselq
                        cpu_dbg_cc,
200 209 dgisselq
                        1'b0, cmd_halt, (!cpu_dbg_stall), 1'b0,
201
                        i_ext_int, cpu_reset, 1'b0, cmd_addr };
202 38 dgisselq
 
203
        //
204
        // The CPU itself
205
        //
206 209 dgisselq
        wire            cpu_lcl_cyc, cpu_lcl_stb,
207
                        cpu_dbg_we,
208 38 dgisselq
                        cpu_op_stall, cpu_pf_stall, cpu_i_count;
209
        wire    [31:0]   cpu_dbg_data;
210 209 dgisselq
        assign cpu_dbg_we = ((dbg_stb)&&(dbg_we)&&(dbg_addr));
211 201 dgisselq
        zipcpu  #(.RESET_ADDRESS(RESET_ADDRESS),
212
                        .ADDRESS_WIDTH(ADDRESS_WIDTH),
213
                        .LGICACHE(LGICACHE),
214
                        .WITH_LOCAL_BUS(0))
215 48 dgisselq
                thecpu(i_clk, cpu_reset, i_ext_int,
216 38 dgisselq
                        cpu_halt, cmd_clear_pf_cache, cmd_addr[4:0], cpu_dbg_we,
217 209 dgisselq
                                dbg_idata, cpu_dbg_stall, cpu_dbg_data,
218 38 dgisselq
                                cpu_dbg_cc, cpu_break,
219
                        o_wb_cyc, o_wb_stb,
220
                                cpu_lcl_cyc, cpu_lcl_stb,
221 201 dgisselq
                                o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
222 56 dgisselq
                                i_wb_ack, i_wb_stall, i_wb_data,
223 201 dgisselq
                                (i_wb_err)||(cpu_lcl_cyc),
224 66 dgisselq
                        cpu_op_stall, cpu_pf_stall, cpu_i_count
225
`ifdef  DEBUG_SCOPE
226 209 dgisselq
                        , o_cpu_debug
227 66 dgisselq
`endif
228
                        );
229 38 dgisselq
 
230
        // Return debug response values
231 209 dgisselq
        assign  dbg_odata = (!dbg_addr)?cmd_data :cpu_dbg_data;
232
        initial dbg_ack = 1'b0;
233 38 dgisselq
        always @(posedge i_clk)
234 209 dgisselq
                dbg_ack <= (dbg_stb)&&(!o_dbg_stall);
235
        assign  dbg_stall= (cpu_dbg_stall)&&(dbg_addr);
236 38 dgisselq
 
237 209 dgisselq
        assign  o_ext_int = (cmd_halt) && (!i_wb_stall);
238 38 dgisselq
 
239 209 dgisselq
        // Make Verilator happy
240
        // verilator lint_off UNUSED
241
        wire    [4:0] unused;
242
        assign  unused = { dbg_cyc, cpu_lcl_stb, cpu_op_stall, cpu_pf_stall, cpu_i_count };
243
        // verilator lint_on  UNUSED
244
 
245 38 dgisselq
endmodule

powered by: WebSVN 2.1.0

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