]>
git.zerfleddert.de Git - fpga-games/blob - galaxian/romgen/romgen.cpp
8 #define MAX_ROM_SIZE 0x4000
10 int main(int argc
, char* argv
[])
13 cerr
<< "romgen by MikeJ version 3.00\n";
21 cerr
<< "\nUsage: romgen <input file> <entity name> <number of address bits>\n";
22 cerr
<< " <format> {registered} {enable}\n";
24 cerr
<< "Now uses bit_vector generics for compatibilty with Xilinx UniSim library\n";
26 cerr
<< "for the format paramater use :\n";
27 cerr
<< " a - rtl model rom array \n";
28 cerr
<< " c - rtl model case statement \n";
29 cerr
<< " b - Xilinx block ram4 (registered output always)\n";
30 cerr
<< " l - Xilinx block ram16 (registered output always)\n";
31 cerr
<< " d - Xilinx distributed ram [not supported yet]\n";
33 cerr
<< "for the registered paramater (optional) use :\n";
34 cerr
<< " r - registered output (combinatorial otherwise) \n";
36 cerr
<< "for the enable paramater (optional) use :\n";
37 cerr
<< " e - clock enable generated \n";
39 cerr
<< "note, generated roms are always 8 bits wide\n";
40 cerr
<< " max 12 address bits for block ram4s\n";
41 cerr
<< " max 14 address bits for block ram16s\n";
42 cerr
<< "for example romgen fred.bin fred_rom 12 c r\n\n";
46 fin
= fopen(argv
[1],"rb");
48 cerr
<< "ERROR : Could not open input file " << argv
[1] <<"\n";
55 sscanf(argv
[4],"%c",&rom_type
);
56 if (argc
> 5) sscanf(argv
[5],"%c",&option_1
);
57 if (argc
> 6) sscanf(argv
[6],"%c",&option_2
);
59 bool format_case
= false;
60 bool format_array
= false;
61 bool format_block
= false;
62 bool format_dist
= false;
63 bool format_clock
= false;
64 bool format_ram16
= false;
65 bool format_ena
= false;
67 cerr
<< "INFO : creating entity : " << argv
[2] << "\n";
70 if ((option_1
== 'r') || (option_1
== 'R'))
72 else if ((option_1
== 'e') || (option_1
== 'E'))
75 cerr
<< "ERROR : output option not supported\n";
82 if ((option_2
== 'r') || (option_2
== 'R'))
84 else if ((option_2
== 'e') || (option_2
== 'E'))
87 cerr
<< "ERROR : output option not supported\n";
92 if ((rom_type
== 'c') || (rom_type
== 'C')) {
93 cerr
<< "INFO : rtl model, case statement \n"; format_case
= true; }
94 else if ((rom_type
== 'a') || (rom_type
== 'A')) {
95 cerr
<< "INFO : rtl model, rom array \n"; format_array
= true; }
96 else if ((rom_type
== 'b') || (rom_type
== 'B')) {
97 cerr
<< "INFO : block4 ram, registered \n"; format_block
= true; format_clock
= true; }
98 else if ((rom_type
== 'l') || (rom_type
== 'L')) {
99 cerr
<< "INFO : block16 ram, registered \n"; format_block
= true; format_clock
= true; format_ram16
= true; }
100 //else if ((rom_type == 'd') || (rom_type == 'D')) {
101 // cerr << "INFO : distributed ram, combinatorial; \n"; format_dist = true; }
103 cerr
<< "ERROR : format not supported\n";
106 if (format_clock
== true)
107 cerr
<< "INFO : registered output\n\n";
109 cerr
<< "INFO : combinatorial output\n\n";
112 // calc number of address bits required
114 int max_addr_bits
= 16;
117 if (format_block
== true) {
118 if (format_ram16
== true) {
126 sscanf(argv
[3],"%d",&addr_bits
);
127 if (addr_bits
< 1 || addr_bits
> max_addr_bits
) {
128 cerr
<< "ERROR : illegal rom size, number of address bits must be between 1 and " << max_addr_bits
<< "\n";
132 // for 14 bits use ram_b16_s1 x data_width
133 // for 13 bits use ram_b16_s2 x data_width/2
134 // for 12 bits use ram_b16_s4 x data_width/4
135 // for<=11 bits use ram_b16_s8 x data_width/8
138 // for 12 bits use ram_b4_s1 x data_width
139 // for 11 bits use ram_b4_s2 x data_width/2
140 // for 10 bits use ram_b4_s4 x data_width/4
141 // for <=9 bits use ram_b4_s8 x data_width/8
142 int rom_size
= (int) pow(2,addr_bits
);
144 int number_of_block_rams
= 1;
145 int block_ram_width
= 8;
146 int block_ram_pwidth
= 0;
147 int block_ram_abits
= 9;
149 if (format_ram16
== true) {
150 block_ram_abits
= 11; // default
151 block_ram_pwidth
= 1;
154 case 14 : number_of_block_rams
= 8; block_ram_width
= 1; block_ram_pwidth
= 0; block_ram_abits
= 14; break;
155 case 13 : number_of_block_rams
= 4; block_ram_width
= 2; block_ram_pwidth
= 0; block_ram_abits
= 13; break;
156 case 12 : number_of_block_rams
= 2; block_ram_width
= 4; block_ram_pwidth
= 0; block_ram_abits
= 12; break;
163 case 12 : number_of_block_rams
= 8; block_ram_width
= 1; block_ram_abits
= 12; break;
164 case 11 : number_of_block_rams
= 4; block_ram_width
= 2; block_ram_abits
= 11; break;
165 case 10 : number_of_block_rams
= 2; block_ram_width
= 4; block_ram_abits
= 10; break;
170 //printf("block ram w : %d ",block_ram_width);
171 //printf("block ram n : %d ",number_of_block_rams);
175 int mem
[MAX_ROM_SIZE
];
184 unsigned int data
= 0;
187 for (i
= 0; i
< MAX_ROM_SIZE
; i
++) mem
[i
] = 0;
191 while (!feof(fin
) && (addr
< rom_size
)) {
192 if (addr
>= MAX_ROM_SIZE
) {
193 cerr
<< "ERROR : file too large\n";
199 //if (addr % 16 == 0) printf("%04x : ",addr);
200 //printf("%02x ",data);
201 //if (addr % 16 == 15) printf("\n");
209 printf("-- generated with romgen v3.0 by MikeJ\n");
210 printf("library ieee;\n");
211 printf(" use ieee.std_logic_1164.all;\n");
212 printf(" use ieee.std_logic_unsigned.all;\n");
213 printf(" use ieee.numeric_std.all;\n");
215 printf("library UNISIM;\n");
216 printf(" use UNISIM.Vcomponents.all;\n");
218 printf("entity %s is\n",argv
[2]);
220 if (format_clock
== true) printf(" CLK : in std_logic;\n");
221 if (format_ena
== true) printf(" ENA : in std_logic;\n");
222 printf(" ADDR : in std_logic_vector(%d downto 0);\n",addr_bits
- 1);
223 printf(" DATA : out std_logic_vector(7 downto 0)\n");
227 printf("architecture RTL of %s is\n",argv
[2]);
232 if (format_block
== true) {
233 printf(" function romgen_str2bv (str : string) return bit_vector is\n");
234 printf(" variable result : bit_vector (str'length*4-1 downto 0);\n");
236 printf(" for i in 0 to str'length-1 loop\n");
237 printf(" case str(str'high-i) is\n");
238 for (i
= 0; i
<16; i
++)
239 printf(" when '%01X' => result(i*4+3 downto i*4) := x\042%01X\042;\n",i
,i
);
240 printf(" when others => null;\n");
241 printf(" end case;\n");
242 printf(" end loop;\n");
243 printf(" return result;\n");
244 printf(" end romgen_str2bv;\n");
247 // xilinx block ram component
248 if (block_ram_pwidth
!= 0) {
249 for (i
= 0; i
< 8; i
++)
250 printf(" attribute INITP_%02X : string;\n",i
);
254 for (i
= 0; i
< rom_inits
; i
++)
255 printf(" attribute INIT_%02X : string;\n",i
);
258 if (format_ram16
== true)
259 printf(" component RAMB16_S%d\n",block_ram_width
+ block_ram_pwidth
);
261 printf(" component RAMB4_S%d\n",block_ram_width
);
263 printf(" --pragma translate_off\n");
264 printf(" generic (\n");
265 if (block_ram_pwidth
!= 0) {
266 for (i
= 0; i
< 8; i
++) {
267 printf(" INITP_%02X : bit_vector (255 downto 0) := x\0420000000000000000000000000000000000000000000000000000000000000000\042",i
);
273 for (i
= 0; i
< rom_inits
; i
++) {
274 printf(" INIT_%02X : bit_vector (255 downto 0) := x\0420000000000000000000000000000000000000000000000000000000000000000\042",i
);
275 if (i
< (rom_inits
- 1)) printf(";");
279 printf(" --pragma translate_on\n");
281 printf(" DO : out std_logic_vector (%d downto 0);\n",block_ram_width
-1);
282 if (block_ram_pwidth
!= 0)
283 printf(" DOP : out std_logic_vector (%d downto 0);\n",block_ram_pwidth
-1);
284 printf(" ADDR : in std_logic_vector (%d downto 0);\n",block_ram_abits
-1);
285 printf(" CLK : in std_logic;\n");
286 printf(" DI : in std_logic_vector (%d downto 0);\n",block_ram_width
-1);
287 if (block_ram_pwidth
!= 0)
288 printf(" DIP : in std_logic_vector (%d downto 0);\n",block_ram_pwidth
-1);
289 printf(" EN : in std_logic;\n");
290 if (format_ram16
== true)
291 printf(" SSR : in std_logic;\n");
293 printf(" RST : in std_logic;\n");
294 printf(" WE : in std_logic \n");
296 printf(" end component;\n");
298 printf(" signal rom_addr : std_logic_vector(%d downto 0);\n",block_ram_abits
- 1);
303 if (format_array
== true) {
305 printf(" type ROM_ARRAY is array(0 to %d) of std_logic_vector(7 downto 0);\n",rom_size
- 1);
306 printf(" constant ROM : ROM_ARRAY := (\n");
307 for (i
= 0; i
< rom_size
; i
++ ) {
308 if (i
% 8 == 0) printf(" ");
309 printf("x\042%02X\042",mem
[i
]);
310 if (i
< (rom_size
- 1)) printf(",");
311 if (i
== (rom_size
- 1)) printf(" ");
312 if (i
% 8 == 7) printf(" -- 0x%04X\n",i
- 7);
319 if (format_case
== true) {
320 printf(" signal rom_addr : std_logic_vector(11 downto 0);\n");
328 if ((format_block
== true) || (format_case
== true)) {
329 printf(" p_addr : process(ADDR)\n");
331 printf(" rom_addr <= (others => '0');\n");
332 printf(" rom_addr(%d downto 0) <= ADDR;\n",addr_bits
- 1);
333 printf(" end process;\n");
338 if (format_block
== true) {
339 for (k
= 0; k
< number_of_block_rams
; k
++){
340 printf(" rom%d : if true generate\n",k
);
342 for (j
= 0; j
< rom_inits
; j
++) {
343 printf(" attribute INIT_%02X of inst : label is \042",j
);
344 switch (block_ram_width
) {
348 for (i
= 0; i
< 256; i
+=8) {
349 data
= ((mem
[(j
*256) + (255 - i
)] & mask
) >> k
);
351 data
+= ((mem
[(j
*256) + (254 - i
)] & mask
) >> k
);
353 data
+= ((mem
[(j
*256) + (253 - i
)] & mask
) >> k
);
355 data
+= ((mem
[(j
*256) + (252 - i
)] & mask
) >> k
);
357 data
+= ((mem
[(j
*256) + (251 - i
)] & mask
) >> k
);
359 data
+= ((mem
[(j
*256) + (250 - i
)] & mask
) >> k
);
361 data
+= ((mem
[(j
*256) + (249 - i
)] & mask
) >> k
);
363 data
+= ((mem
[(j
*256) + (248 - i
)] & mask
) >> k
);
369 mask
= 0x3 << (k
* 2);
370 for (i
= 0; i
< 128; i
+=4) {
371 data
= ((mem
[(j
*128) + (127 - i
)] & mask
) >> k
* 2);
373 data
+= ((mem
[(j
*128) + (126 - i
)] & mask
) >> k
* 2);
375 data
+= ((mem
[(j
*128) + (125 - i
)] & mask
) >> k
* 2);
377 data
+= ((mem
[(j
*128) + (124 - i
)] & mask
) >> k
* 2);
383 mask
= 0xF << (k
* 4);
384 for (i
= 0; i
< 64; i
+=2) {
385 data
= ((mem
[(j
*64) + (63 - i
)] & mask
) >> k
* 4);
387 data
+= ((mem
[(j
*64) + (62 - i
)] & mask
) >> k
* 4);
395 for (i
= 0; i
< 32; i
++) {
396 data
= ((mem
[(j
*32) + (31 - i
)]));
406 if (format_ram16
== true)
407 printf(" inst : RAMB16_S%d\n",block_ram_width
+ block_ram_pwidth
);
409 printf(" inst : RAMB4_S%d\n",block_ram_width
);
411 printf(" --pragma translate_off\n");
412 printf(" generic map (\n");
414 if (block_ram_pwidth
!= 0) {
415 for (i
= 0; i
< 8; i
++) {
416 printf(" INITP_%02X => x\0420000000000000000000000000000000000000000000000000000000000000000\042",i
);
422 for (i
= 0; i
< rom_inits
; i
++) {
423 printf(" INIT_%02X => romgen_str2bv(inst'INIT_%02X)",i
,i
);
424 if (i
< (rom_inits
- 1)) printf(",");
428 printf(" --pragma translate_on\n");
429 printf(" port map (\n");
430 printf(" DO => DATA(%d downto %d),\n",((k
+1) * block_ram_width
)-1,k
*block_ram_width
);
431 if (block_ram_pwidth
!= 0)
432 printf(" DOP => open,\n");
433 printf(" ADDR => rom_addr,\n");
434 printf(" CLK => CLK,\n");
435 printf(" DI => \042");
436 for (i
= 0; i
< block_ram_width
-1; i
++) printf("0");
438 if (block_ram_pwidth
!= 0) {
439 printf(" DIP => \042");
440 for (i
= 0; i
< block_ram_pwidth
-1; i
++) printf("0");
443 if (format_ena
== true)
444 printf(" EN => ENA,\n");
446 printf(" EN => '1',\n");
448 if (format_ram16
== true)
449 printf(" SSR => '0',\n");
451 printf(" RST => '0',\n");
452 printf(" WE => '0'\n");
454 printf(" end generate;\n");
460 if (format_array
== true) {
461 if (format_clock
== true)
462 printf(" p_rom : process\n");
464 printf(" p_rom : process(ADDR)\n");
466 if (format_clock
== true)
467 printf(" wait until rising_edge(CLK);\n");
468 if (format_ena
== true)
469 printf(" if (ENA = '1') then\n ");
470 printf(" DATA <= ROM(to_integer(unsigned(ADDR)));\n");
471 if (format_ena
== true)
472 printf(" end if;\n");
473 printf(" end process;\n");
478 if (format_case
== true) {
479 if (format_clock
== true)
480 printf(" p_rom : process\n");
482 printf(" p_rom : process(rom_addr)\n");
484 if (format_clock
== true)
485 printf(" wait until rising_edge(CLK);\n");
486 if (format_ena
== true)
487 printf(" if (ENA = '1') then\n");
489 printf(" DATA <= (others => '0');\n");
490 printf(" case rom_addr is\n");
491 for (i
= 0; i
< rom_size
; i
++ ) {
492 printf(" when x\042%03X\042 => DATA <= x\042%02X\042;\n",i
,mem
[i
]);
494 printf(" when others => DATA <= (others => '0');\n");
495 printf(" end case;\n");
496 if (format_ena
== true)
497 printf(" end if;\n");
498 printf(" end process;\n");
501 printf("end RTL;\n");