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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [rtl/] [core/] [memops.v] - Blame information for rev 201

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

Line No. Rev Author Line
1 201 dgisselq
////////////////////////////////////////////////////////////////////////////////
2 3 dgisselq
//
3
// Filename:    memops.v
4
//
5
// Project:     Zip CPU -- a small, lightweight, RISC CPU soft core
6
//
7
// Purpose:     A memory unit to support a CPU.
8
//
9
//      In the interests of code simplicity, this memory operator is 
10
//      susceptible to unknown results should a new command be sent to it
11
//      before it completes the last one.  Unpredictable results might then
12
//      occurr.
13
//
14 36 dgisselq
//      20150919 -- Added support for handling BUS ERR's (i.e., the WB
15
//              error signal).
16
//
17 3 dgisselq
// Creator:     Dan Gisselquist, Ph.D.
18 69 dgisselq
//              Gisselquist Technology, LLC
19 3 dgisselq
//
20 201 dgisselq
////////////////////////////////////////////////////////////////////////////////
21 3 dgisselq
//
22 201 dgisselq
// Copyright (C) 2015,2017, Gisselquist Technology, LLC
23 3 dgisselq
//
24
// This program is free software (firmware): you can redistribute it and/or
25
// modify it under the terms of  the GNU General Public License as published
26
// by the Free Software Foundation, either version 3 of the License, or (at
27
// your option) any later version.
28
//
29
// This program is distributed in the hope that it will be useful, but WITHOUT
30
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
31
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
32
// for more details.
33
//
34 201 dgisselq
// You should have received a copy of the GNU General Public License along
35
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
36
// target there if the PDF file isn't present.)  If not, see
37
// <http://www.gnu.org/licenses/> for a copy.
38
//
39 3 dgisselq
// License:     GPL, v3, as defined and found on www.gnu.org,
40
//              http://www.gnu.org/licenses/gpl.html
41
//
42
//
43 201 dgisselq
////////////////////////////////////////////////////////////////////////////////
44 3 dgisselq
//
45 201 dgisselq
//
46 69 dgisselq
module  memops(i_clk, i_rst, i_stb, i_lock,
47 2 dgisselq
                i_op, i_addr, i_data, i_oreg,
48 36 dgisselq
                        o_busy, o_valid, o_err, o_wreg, o_result,
49
                o_wb_cyc_gbl, o_wb_cyc_lcl,
50
                        o_wb_stb_gbl, o_wb_stb_lcl,
51 201 dgisselq
                        o_wb_we, o_wb_addr, o_wb_data, o_wb_sel,
52 36 dgisselq
                i_wb_ack, i_wb_stall, i_wb_err, i_wb_data);
53 201 dgisselq
        parameter       ADDRESS_WIDTH=30, IMPLEMENT_LOCK=0, WITH_LOCAL_BUS=0;
54
        localparam      AW=ADDRESS_WIDTH;
55 2 dgisselq
        input                   i_clk, i_rst;
56 69 dgisselq
        input                   i_stb, i_lock;
57 2 dgisselq
        // CPU interface
58 201 dgisselq
        input           [2:0]    i_op;
59 2 dgisselq
        input           [31:0]   i_addr;
60
        input           [31:0]   i_data;
61
        input           [4:0]    i_oreg;
62
        // CPU outputs
63
        output  wire            o_busy;
64
        output  reg             o_valid;
65 36 dgisselq
        output  reg             o_err;
66 2 dgisselq
        output  reg     [4:0]    o_wreg;
67
        output  reg     [31:0]   o_result;
68
        // Wishbone outputs
69 69 dgisselq
        output  wire            o_wb_cyc_gbl;
70
        output  reg             o_wb_stb_gbl;
71
        output  wire            o_wb_cyc_lcl;
72
        output  reg             o_wb_stb_lcl;
73
        output  reg             o_wb_we;
74 48 dgisselq
        output  reg     [(AW-1):0]       o_wb_addr;
75
        output  reg     [31:0]   o_wb_data;
76 201 dgisselq
        output  reg     [3:0]    o_wb_sel;
77 2 dgisselq
        // Wishbone inputs
78 36 dgisselq
        input                   i_wb_ack, i_wb_stall, i_wb_err;
79 2 dgisselq
        input           [31:0]   i_wb_data;
80
 
81 69 dgisselq
        reg     r_wb_cyc_gbl, r_wb_cyc_lcl;
82 36 dgisselq
        wire    gbl_stb, lcl_stb;
83 201 dgisselq
        assign  lcl_stb = (i_stb)&&(WITH_LOCAL_BUS!=0)&&(i_addr[31:24]==8'hff);
84
        assign  gbl_stb = (i_stb)&&((WITH_LOCAL_BUS==0)||(i_addr[31:24]!=8'hff));
85 36 dgisselq
 
86 69 dgisselq
        initial r_wb_cyc_gbl = 1'b0;
87
        initial r_wb_cyc_lcl = 1'b0;
88 2 dgisselq
        always @(posedge i_clk)
89
                if (i_rst)
90 36 dgisselq
                begin
91 69 dgisselq
                        r_wb_cyc_gbl <= 1'b0;
92
                        r_wb_cyc_lcl <= 1'b0;
93
                end else if ((r_wb_cyc_gbl)||(r_wb_cyc_lcl))
94 36 dgisselq
                begin
95
                        if ((i_wb_ack)||(i_wb_err))
96
                        begin
97 69 dgisselq
                                r_wb_cyc_gbl <= 1'b0;
98
                                r_wb_cyc_lcl <= 1'b0;
99 36 dgisselq
                        end
100
                end else if (i_stb) // New memory operation
101
                begin // Grab the wishbone
102 69 dgisselq
                        r_wb_cyc_lcl <= lcl_stb;
103
                        r_wb_cyc_gbl <= gbl_stb;
104 36 dgisselq
                end
105 3 dgisselq
        always @(posedge i_clk)
106 36 dgisselq
                if (o_wb_cyc_gbl)
107
                        o_wb_stb_gbl <= (o_wb_stb_gbl)&&(i_wb_stall);
108 3 dgisselq
                else
109 36 dgisselq
                        o_wb_stb_gbl <= gbl_stb; // Grab wishbone on new operation
110 3 dgisselq
        always @(posedge i_clk)
111 36 dgisselq
                if (o_wb_cyc_lcl)
112
                        o_wb_stb_lcl <= (o_wb_stb_lcl)&&(i_wb_stall);
113
                else
114
                        o_wb_stb_lcl  <= lcl_stb; // Grab wishbone on new operation
115 201 dgisselq
 
116
        reg     [3:0]    r_op;
117 36 dgisselq
        always @(posedge i_clk)
118 3 dgisselq
                if (i_stb)
119
                begin
120 201 dgisselq
                        o_wb_we   <= i_op[0];
121
                        casez({ i_op[2:1], i_addr[1:0] })
122
`ifdef  ZERO_ON_IDLE
123
                        4'b100?: o_wb_data <= { i_data[15:0], 16'h00 };
124
                        4'b101?: o_wb_data <= { 16'h00, i_data[15:0] };
125
                        4'b1100: o_wb_data <= {         i_data[7:0], 24'h00 };
126
                        4'b1101: o_wb_data <= {  8'h00, i_data[7:0], 16'h00 };
127
                        4'b1110: o_wb_data <= { 16'h00, i_data[7:0],  8'h00 };
128
                        4'b1111: o_wb_data <= { 24'h00, i_data[7:0] };
129
`else
130
                        4'b10??: o_wb_data <= { (2){ i_data[15:0] } };
131
                        4'b11??: o_wb_data <= { (4){ i_data[7:0] } };
132
`endif
133
                        default: o_wb_data <= i_data;
134
                        endcase
135
 
136
                        o_wb_addr <= i_addr[(AW+1):2];
137
`ifdef  SET_SEL_ON_READ
138
                        if (i_op[0] == 1'b0)
139
                                o_wb_sel <= 4'hf;
140
                        else
141
`endif
142
                        casez({ i_op[2:1], i_addr[1:0] })
143
                        4'b01??: o_wb_sel <= 4'b1111;
144
                        4'b100?: o_wb_sel <= 4'b1100;
145
                        4'b101?: o_wb_sel <= 4'b0011;
146
                        4'b1100: o_wb_sel <= 4'b1000;
147
                        4'b1101: o_wb_sel <= 4'b0100;
148
                        4'b1110: o_wb_sel <= 4'b0010;
149
                        4'b1111: o_wb_sel <= 4'b0001;
150
                        default: o_wb_sel <= 4'b1111;
151
                        endcase
152
                        r_op <= { i_op[2:1] , i_addr[1:0] };
153 2 dgisselq
                end
154 201 dgisselq
`ifdef  ZERO_ON_IDLE
155
                else if ((!o_wb_cyc_gbl)&&(!o_wb_cyc_lcl))
156
                begin
157
                        o_wb_we   <= 1'b0;
158
                        o_wb_addr <= 0;
159
                        o_wb_data <= 32'h0;
160
                        o_wb_sel  <= 4'h0;
161
                end
162
`endif
163 2 dgisselq
 
164
        initial o_valid = 1'b0;
165
        always @(posedge i_clk)
166 36 dgisselq
                o_valid <= ((o_wb_cyc_gbl)||(o_wb_cyc_lcl))&&(i_wb_ack)&&(~o_wb_we);
167
        initial o_err = 1'b0;
168
        always @(posedge i_clk)
169
                o_err <= ((o_wb_cyc_gbl)||(o_wb_cyc_lcl))&&(i_wb_err);
170
        assign  o_busy = (o_wb_cyc_gbl)||(o_wb_cyc_lcl);
171 2 dgisselq
 
172
        always @(posedge i_clk)
173 3 dgisselq
                if (i_stb)
174 2 dgisselq
                        o_wreg    <= i_oreg;
175
        always @(posedge i_clk)
176 201 dgisselq
`ifdef  ZERO_ON_IDLE
177
                if (!i_wb_ack)
178
                        o_result <= 32'h0;
179
                else
180
`endif
181
                casez(r_op)
182
                4'b01??: o_result <= i_wb_data;
183
                4'b100?: o_result <= { 16'h00, i_wb_data[31:16] };
184
                4'b101?: o_result <= { 16'h00, i_wb_data[15: 0] };
185
                4'b1100: o_result <= { 24'h00, i_wb_data[31:24] };
186
                4'b1101: o_result <= { 24'h00, i_wb_data[23:16] };
187
                4'b1110: o_result <= { 24'h00, i_wb_data[15: 8] };
188
                4'b1111: o_result <= { 24'h00, i_wb_data[ 7: 0] };
189
                default: o_result <= i_wb_data;
190
                endcase
191 69 dgisselq
 
192
        generate
193
        if (IMPLEMENT_LOCK != 0)
194
        begin
195
                reg     lock_gbl, lock_lcl;
196
 
197
                initial lock_gbl = 1'b0;
198
                initial lock_lcl = 1'b0;
199
 
200
                always @(posedge i_clk)
201
                begin
202
                        lock_gbl <= (i_lock)&&((r_wb_cyc_gbl)||(lock_gbl));
203
                        lock_lcl <= (i_lock)&&((r_wb_cyc_lcl)||(lock_lcl));
204
                end
205
 
206
                assign  o_wb_cyc_gbl = (r_wb_cyc_gbl)||(lock_gbl);
207
                assign  o_wb_cyc_lcl = (r_wb_cyc_lcl)||(lock_lcl);
208
        end else begin
209
                assign  o_wb_cyc_gbl = (r_wb_cyc_gbl);
210
                assign  o_wb_cyc_lcl = (r_wb_cyc_lcl);
211
        end endgenerate
212 2 dgisselq
endmodule

powered by: WebSVN 2.1.0

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