add licenses and readme
[rv32.git] / software / make_block_memory.sh
1 #!/bin/bash
2 # Copyright 2018 Jacob Lifshay
3 #
4 # Permission is hereby granted, free of charge, to any person obtaining a copy
5 # of this software and associated documentation files (the "Software"), to deal
6 # in the Software without restriction, including without limitation the rights
7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 # copies of the Software, and to permit persons to whom the Software is
9 # furnished to do so, subject to the following conditions:
10 #
11 # The above copyright notice and this permission notice shall be included in all
12 # copies or substantial portions of the Software.
13 #
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 # SOFTWARE.
21
22 # 32KiB
23 memory_size=$((32<<10))
24 # 16kbit
25 block_size_log_2=11
26
27 output_file=""
28
29 function open_output_file()
30 {
31 output_file="$1"
32 exec >"$1"
33 }
34
35 function error()
36 {
37 echo "error:" "$@" >&2
38 if [[ "" != "$output_file" ]]; then
39 rm "$output_file"
40 fi
41 exit 1
42 }
43
44 chunk_size_log_2=$((block_size_log_2+2))
45 chunk_size=$((1<<chunk_size_log_2))
46 chunk_count=$((memory_size / chunk_size))
47 ((memory_size % chunk_size == 0)) || error "memory_size must be a multiple of chunk_size"
48
49 if [[ "$1" == "-v" ]]; then
50 open_output_file block_memory.v
51 cat <<EOF
52 /*
53 * Copyright 2018 Jacob Lifshay
54 *
55 * Permission is hereby granted, free of charge, to any person obtaining a copy
56 * of this software and associated documentation files (the "Software"), to deal
57 * in the Software without restriction, including without limitation the rights
58 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
59 * copies of the Software, and to permit persons to whom the Software is
60 * furnished to do so, subject to the following conditions:
61 *
62 * The above copyright notice and this permission notice shall be included in all
63 * copies or substantial portions of the Software.
64 *
65 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
66 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
67 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
68 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
69 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
70 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
71 * SOFTWARE.
72 *
73 */
74 \`timescale 1ns / 1ps
75
76 module block_memory(
77 input clk,
78 input [31:0] a_ram_address,
79 input [3:0] a_write_enable,
80 input [31:0] a_write_input,
81 output reg [31:0] a_read_output,
82 input [31:0] b_ram_address,
83 output reg [31:0] b_read_output
84 );
85 EOF
86
87 for((i = 0; i < chunk_count; i++)); do
88 cat <<EOF
89
90 wire a_enable_${i} = a_ram_address[31:${block_size_log_2}] == ${i};
91 wire b_enable_${i} = b_ram_address[31:${block_size_log_2}] == ${i};
92 wire [3:0] a_write_enable_${i} = {4{a_enable_${i}}} & a_write_enable;
93 wire [31:0] a_read_output_${i};
94 wire [31:0] b_read_output_${i};
95 EOF
96 for byte in {0..3}; do
97 cat <<EOF
98 block_memory_16kbit #(
99 .initial_file("software/ram_${i}_byte${byte}.hex")
100 ) ram_${i}_byte${byte}(
101 .clk(clk),
102 .port_a_address(a_ram_address[$((block_size_log_2 - 1)):0]),
103 .port_a_write_enable(a_write_enable_${i}[${byte}]),
104 .port_a_write_input(a_write_input[$((byte * 8 + 7)):$((byte * 8))]),
105 .port_a_read_output(a_read_output_${i}[$((byte * 8 + 7)):$((byte * 8))]),
106 .port_b_address(b_ram_address[$((block_size_log_2 - 1)):0]),
107 .port_b_read_output(b_read_output_${i}[$((byte * 8 + 7)):$((byte * 8))])
108 );
109
110 EOF
111 done
112 done
113
114 cat <<EOF
115
116 always @* begin
117 case(a_ram_address[31:${block_size_log_2}])
118 EOF
119
120 for((i = 0; i < chunk_count; i++)); do
121 cat <<EOF
122 ${i}: a_read_output = a_read_output_${i};
123 EOF
124 done
125
126 cat <<EOF
127 default: a_read_output = 32'hXXXXXXXX;
128 endcase
129 end
130
131 always @* begin
132 case(b_ram_address[31:${block_size_log_2}])
133 EOF
134
135 for((i = 0; i < chunk_count; i++)); do
136 cat <<EOF
137 ${i}: b_read_output = b_read_output_${i};
138 EOF
139 done
140
141 cat <<EOF
142 default: b_read_output = 32'hXXXXXXXX;
143 endcase
144 end
145 endmodule
146 EOF
147 exit 0
148 elif [[ "$1" == "-s" ]]; then
149 open_output_file generate_hex_files.sh
150 chmod +x generate_hex_files.sh
151 cat <<EOF
152 #!/bin/bash
153 # Copyright 2018 Jacob Lifshay
154 #
155 # Permission is hereby granted, free of charge, to any person obtaining a copy
156 # of this software and associated documentation files (the "Software"), to deal
157 # in the Software without restriction, including without limitation the rights
158 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
159 # copies of the Software, and to permit persons to whom the Software is
160 # furnished to do so, subject to the following conditions:
161 #
162 # The above copyright notice and this permission notice shall be included in all
163 # copies or substantial portions of the Software.
164 #
165 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
166 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
167 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
168 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
169 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
170 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
171 # SOFTWARE.
172
173 mapfile -t words < <(hexdump -v -e '/4 "%08X\n"' < ram.bin)
174 chunk_size=${chunk_size}
175 chunk_count=${chunk_count}
176 EOF
177 cat <<'EOF'
178 if (( chunk_size * chunk_count != 4 * ${#words[@]} )); then
179 echo "ram.bin is the wrong size: expected $((chunk_size * chunk_count / 4)) words, got ${#words[@]}" >&2
180 exit 1
181 fi
182 word_index=0
183 for((chunk=0;chunk<chunk_count;chunk++)); do
184 exec 3>"ram_${chunk}_byte0.hex" 4>"ram_${chunk}_byte1.hex" 5>"ram_${chunk}_byte2.hex" 6>"ram_${chunk}_byte3.hex"
185 for((i=0;i<chunk_size;i+=4)); do
186 word="${words[word_index++]}"
187 echo "${word:6:2}" >&3
188 echo "${word:4:2}" >&4
189 echo "${word:2:2}" >&5
190 echo "${word:0:2}" >&6
191 done
192 done
193 exit 0
194 EOF
195 else
196 error $'unknown option\nusage: '"$0"$' [-v|-s]\n-v\tgenerate block_memory.v\n-s\tgenerate generate_hex_files.sh'
197 fi
198