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

Subversion Repositories ao68000

[/] [ao68000/] [trunk/] [sw/] [ao68000_tool/] [GenerateMicrocode.java] - Blame information for rev 18

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

Line No. Rev Author Line
1 12 alfik
/*
2
 * Copyright 2010, Aleksander Osman, alfik@poczta.fm. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without modification, are
5
 * permitted provided that the following conditions are met:
6
 *
7
 *  1. Redistributions of source code must retain the above copyright notice, this list of
8
 *     conditions and the following disclaimer.
9
 *
10
 *  2. Redistributions in binary form must reproduce the above copyright notice, this list
11
 *     of conditions and the following disclaimer in the documentation and/or other materials
12
 *     provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
15
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
 
25
package ao68000_tool;
26
 
27
import java.io.OutputStream;
28
import java.io.FileInputStream;
29
import java.io.FileOutputStream;
30
import java.io.File;
31
import java.util.Vector;
32
import java.util.HashMap;
33
import java.util.HashSet;
34
 
35
class GenerateMicrocode {
36
    static void entry(boolean newline, String name) throws Exception {
37
        /*
38
         * if newline is true: end of last line
39
         * if name is "offset_" + label: branch label
40
         * if name is "label_" + label: label declaration
41
         */
42
 
43
        if(ParseParams.prefixes == null || labels == null || lines == null) throw new Exception("Entry validator not initialized.");
44
 
45
        // save last line
46
        if(newline == true && current_line != null && current_line.size() > 0) lines.add(current_line);
47
        // prepare a new line
48
        if(newline == true) current_line = new HashMap<String,String>();
49
 
50
        // save label location
51
        if(name.startsWith("label_")) {
52
            String label = name.substring(6);
53
            if(labels.containsKey(label)) throw new Exception("Double label declaration: " + label);
54
            labels.put(label, lines.size());
55
            return;
56
        }
57
 
58
        // get prefix
59
        String prefix = "PROCEDURE_";
60
        if(name.startsWith("offset_")) {
61
            String label = name.substring(7);
62
            name = "label_" + label;
63
        }
64
        else {
65
            prefix = null;
66
            for(String p : ParseParams.prefixes) {
67
                if(name.startsWith(p)) {
68
                    prefix = p;
69
                    break;
70
                }
71
            }
72
        }
73
 
74
        if(prefix == null) throw new Exception("Unknown prefix for name: " + name);
75
 
76
        // check for double prefix
77
        if(current_line.containsKey(prefix)) throw new Exception("Double prefix call: " + prefix);
78
 
79
        // extend current line
80
        current_line.put(prefix, name);
81
    }
82
 
83
    static void fill_bit_part(int array[], int start, int end, int value) throws Exception {
84
        while(start <= end) {
85
            int bit = value & 0x1;
86
 
87
            array[start] = bit;
88
 
89
            value >>= 1;
90
            start++;
91
        }
92
    }
93
    static void final_process(OutputStream out) throws Exception {
94
        if(ParseParams.prefixes == null || labels == null || lines == null) throw new Exception("Final validator not initialized.");
95
        // add last line
96
        if(current_line != null && current_line.size() > 0) lines.add(current_line);
97
 
98
 
99
        int i=0;
100
        // resolve labels
101
        for(HashMap<String,String> line : lines) {
102
            if(line.containsKey("PROCEDURE_")) {
103
                String value = line.get("PROCEDURE_");
104
 
105
                if(value.startsWith("label_")) {
106
                    String label = value.substring(6);
107
 
108
                    if(labels.containsKey(label) == false) throw new Exception("Unresolved label: " + label);
109
                    int label_value = labels.get(label);
110
 
111
                    int delta = label_value - i;
112
 
113
                    if(delta < 0 || delta > 15) throw new Exception("Label: " + label + " out of bounds: " + delta);
114
                    line.put("PROCEDURE_", "value_" + delta);
115
                }
116
            }
117
            i++;
118
        }
119
 
120
        // prepare output header
121
        int depth = 1;
122
        while(depth < lines.size()) depth *= 2;
123
 
124
        out.write(new String("DEPTH = " + depth + ";\n").getBytes());
125
        out.write(new String("WIDTH = " + bit_line.length + ";\n").getBytes());
126
        out.write(new String("ADDRESS_RADIX = DEC;\n").getBytes());
127
        out.write(new String("DATA_RADIX = BIN;\n").getBytes());
128
        out.write(new String("CONTENT\n").getBytes());
129
        out.write(new String("BEGIN\n").getBytes());
130
 
131
        i=0;
132
        HashSet<String> set = new HashSet<String>();
133
        Vector<String> bit_lines = new Vector<String>();
134
        // prepare final bit array
135
        for(HashMap<String,String> line : lines) {
136
            for(int j=0; j<bit_line.length; j++) bit_line[j] = 0;
137
 
138
            for(String prefix : ParseParams.prefixes) {
139
                if(line.containsKey(prefix)) {
140
                    String string_value = line.get(prefix);
141
 
142
                    int value = 0;
143
                    if(string_value.startsWith("value_")) {
144
                        value = Integer.parseInt(string_value.substring(6));
145
                    }
146
                    else {
147
                        if(ParseParams.name_values.containsKey(string_value) == false) throw new Exception("Unknown value: " + string_value);
148
                        value = ParseParams.name_values.get(string_value);
149
                    }
150
                    int start = ParseParams.prefix_locations.get(prefix + "start");
151
                    int end = ParseParams.prefix_locations.get(prefix + "end");
152
 
153
                    fill_bit_part(bit_line, start, end, value);
154
                }
155
            }
156
 
157
            // prepare output
158
            String addr = "" + i + ": ";
159
            while(addr.length() < 8) addr = " " + addr;
160
            out.write(new String(addr).getBytes());
161
 
162
            String bits = "";
163
            for(int j=bit_line.length-1; j>=0; j--) {
164
                bits += bit_line[j];
165
            }
166
            set.add(bits);
167
            bit_lines.add(bits);
168
            out.write(new String(bits + ";\n").getBytes());
169
 
170
            i++;
171
        }
172
        out.write(new String("END;\n").getBytes());
173
 
174
 
175
        // prepare a compact microcode with a microcode decoder
176
        // microcode reduced to 500x8 bits = 4000 bits, but microcode decoder takes about 1000 LE
177
        // so currently unused
178
/*
179
        i = set.size();
180
        int bit_size = 0;
181
        while(i > 0) {
182
            bit_size++;
183
            i /= 2;
184
        }
185
        System.out.println("Set size: " + set.size() + ", bit size: " + bit_size + ", bit_line.length: " + bit_line.length);
186
 
187
        String empty_line = "";
188
        i = 0;
189
        while(i < bit_line.length) {
190
            empty_line += "0";
191
            i++;
192
        }
193
 
194
 
195
        String verilog = "assign micro_data =" + "\n";
196
 
197
        verilog += "(encoded == " + bit_size + "'d" + 0 + ") ? " + bit_line.length + "'b" + empty_line + " :" + "\n";
198
        HashMap<String, Integer> bit_line_numbers = new HashMap<String, Integer>();
199
        i = 1;
200
        for(String line : set) {
201
            verilog += "(encoded == " + bit_size + "'d" + i + ") ? " + bit_line.length + "'b" + line + " :" + "\n";
202
 
203
            bit_line_numbers.put(line, i);
204
            i++;
205
        }
206
        verilog += bit_line.length + "'b" + empty_line + ";" + "\n";
207
 
208
        i=0;
209
        for(String line : bit_lines) {
210
            String addr = "" + i + ": ";
211
            while(addr.length() < 8) addr = " " + addr;
212
            System.out.print(addr);
213
 
214
            String content = "" + bit_line_numbers.get(line) + ";";
215
            System.out.println(content);
216
 
217
            i++;
218
        }
219
        System.out.println("Verilog:\n" + verilog);
220
*/
221
    }
222
    static String get_microcode_defines() throws Exception {
223
        if(ParseParams.prefix_locations == null || ParseParams.prefixes == null) throw new Exception("No prefix_locations or prefixes set.");
224
 
225
        String output = "";
226
 
227
        for(String s : ParseParams.prefixes) {
228
            int start = ParseParams.prefix_locations.get(s + "start");
229
            int end = ParseParams.prefix_locations.get(s + "end");
230
 
231
            String short_name = s.substring(0, s.length()-1);
232
            short_name = short_name.toLowerCase();
233
 
234
            String str = "`define MICRO_DATA_" + short_name;
235
            while(str.length() < 85) str += " ";
236
            output +=  str + "micro_data[" + end + ":" + start + "]\n";
237
        }
238
        output += "\n";
239
 
240
        for(String label : labels.keySet()) {
241
            if(label.startsWith("MICROPC_")) {
242
                String str = "`define " + label;
243
                while(str.length() < 85) str += " ";
244
                output += str + "9'd" + labels.get(label) + "\n";
245
            }
246
        }
247
        return output;
248
    }
249
    static void generate(OutputStream microcode_os, String file_name) throws Exception {
250
        bit_line = new int[ParseParams.control_bit_offset];
251
        lines = new Vector<HashMap<String,String>>();
252
        labels = new HashMap<String,Integer>();
253
 
254
        Microcode.microcode(new Parser());
255
 
256
        final_process(microcode_os);
257
        String locations = get_microcode_defines();
258
 
259
        // load file
260
        File file = new File(file_name);
261
        byte bytes[] = new byte[(int)file.length()];
262
        FileInputStream in = new FileInputStream(file);
263
        if( in.read(bytes) != bytes.length ) throw new Exception("Can not read from file: " + file.getCanonicalPath());
264
        in.close();
265
 
266
        // find 'MICROCODE - DO NOT EDIT BELOW' and 'MICROCODE - DO NOT EDIT ABOVE' substrings
267
        String all_string = new String(bytes);
268
        int start_index = all_string.indexOf("MICROCODE - DO NOT EDIT BELOW");
269
        if(start_index == -1) throw new Exception("Can not find 'MICROCODE - DO NOT EDIT BELOW' substring in " + file.getCanonicalPath());
270
        start_index += new String("MICROCODE - DO NOT EDIT BELOW").length();
271
        int end_index = all_string.indexOf("MICROCODE - DO NOT EDIT ABOVE");
272
        if(end_index == -1) throw new Exception("Can not find 'MICROCODE - DO NOT EDIT ABOVE' substring in " + file.getCanonicalPath());
273
 
274
        String output_string = all_string.substring(0, start_index) + "\n" + locations + "// " + all_string.substring(end_index, all_string.length());
275
 
276
        FileOutputStream out = new FileOutputStream(file);
277
        out.write(output_string.getBytes());
278
        out.close();
279
    }
280
    static HashMap<String, String> current_line;
281
    static Vector<HashMap<String, String>> lines;
282
    static HashMap<String, Integer> labels;
283
    static int bit_line[];
284
}

powered by: WebSVN 2.1.0

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