mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Merge pull request #859 from smunaut/ice40_braminit
iCE40 BRAM primitives init from file
This commit is contained in:
		
						commit
						2ace1b0041
					
				
					 4 changed files with 212 additions and 37 deletions
				
			
		| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OBJS += techlibs/ice40/synth_ice40.o
 | 
					OBJS += techlibs/ice40/synth_ice40.o
 | 
				
			||||||
 | 
					OBJS += techlibs/ice40/ice40_braminit.o
 | 
				
			||||||
OBJS += techlibs/ice40/ice40_ffssr.o
 | 
					OBJS += techlibs/ice40/ice40_ffssr.o
 | 
				
			||||||
OBJS += techlibs/ice40/ice40_ffinit.o
 | 
					OBJS += techlibs/ice40/ice40_ffinit.o
 | 
				
			||||||
OBJS += techlibs/ice40/ice40_opt.o
 | 
					OBJS += techlibs/ice40/ice40_opt.o
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -326,6 +326,8 @@ module SB_RAM40_4K (
 | 
				
			||||||
	parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
						parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
	parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
						parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parameter INIT_FILE = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
`ifndef BLACKBOX
 | 
					`ifndef BLACKBOX
 | 
				
			||||||
	wire [15:0] WMASK_I;
 | 
						wire [15:0] WMASK_I;
 | 
				
			||||||
	wire [15:0] RMASK_I;
 | 
						wire [15:0] RMASK_I;
 | 
				
			||||||
| 
						 | 
					@ -408,6 +410,9 @@ module SB_RAM40_4K (
 | 
				
			||||||
	reg [15:0] memory [0:255];
 | 
						reg [15:0] memory [0:255];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	initial begin
 | 
						initial begin
 | 
				
			||||||
 | 
							if (INIT_FILE != "")
 | 
				
			||||||
 | 
								$readmemh(INIT_FILE, memory);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
			for (i=0; i<16; i=i+1) begin
 | 
								for (i=0; i<16; i=i+1) begin
 | 
				
			||||||
`ifdef YOSYS
 | 
					`ifdef YOSYS
 | 
				
			||||||
				memory[ 0*16 + i] <= INIT_0[16*i +: 16];
 | 
									memory[ 0*16 + i] <= INIT_0[16*i +: 16];
 | 
				
			||||||
| 
						 | 
					@ -504,6 +509,8 @@ module SB_RAM40_4KNR (
 | 
				
			||||||
	parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
						parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
	parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
						parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parameter INIT_FILE = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SB_RAM40_4K #(
 | 
						SB_RAM40_4K #(
 | 
				
			||||||
		.WRITE_MODE(WRITE_MODE),
 | 
							.WRITE_MODE(WRITE_MODE),
 | 
				
			||||||
		.READ_MODE (READ_MODE ),
 | 
							.READ_MODE (READ_MODE ),
 | 
				
			||||||
| 
						 | 
					@ -522,7 +529,8 @@ module SB_RAM40_4KNR (
 | 
				
			||||||
		.INIT_C    (INIT_C    ),
 | 
							.INIT_C    (INIT_C    ),
 | 
				
			||||||
		.INIT_D    (INIT_D    ),
 | 
							.INIT_D    (INIT_D    ),
 | 
				
			||||||
		.INIT_E    (INIT_E    ),
 | 
							.INIT_E    (INIT_E    ),
 | 
				
			||||||
		.INIT_F    (INIT_F    )
 | 
							.INIT_F    (INIT_F    ),
 | 
				
			||||||
 | 
							.INIT_FILE (INIT_FILE )
 | 
				
			||||||
	) RAM (
 | 
						) RAM (
 | 
				
			||||||
		.RDATA(RDATA),
 | 
							.RDATA(RDATA),
 | 
				
			||||||
		.RCLK (~RCLKN),
 | 
							.RCLK (~RCLKN),
 | 
				
			||||||
| 
						 | 
					@ -566,6 +574,8 @@ module SB_RAM40_4KNW (
 | 
				
			||||||
	parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
						parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
	parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
						parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parameter INIT_FILE = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SB_RAM40_4K #(
 | 
						SB_RAM40_4K #(
 | 
				
			||||||
		.WRITE_MODE(WRITE_MODE),
 | 
							.WRITE_MODE(WRITE_MODE),
 | 
				
			||||||
		.READ_MODE (READ_MODE ),
 | 
							.READ_MODE (READ_MODE ),
 | 
				
			||||||
| 
						 | 
					@ -584,7 +594,8 @@ module SB_RAM40_4KNW (
 | 
				
			||||||
		.INIT_C    (INIT_C    ),
 | 
							.INIT_C    (INIT_C    ),
 | 
				
			||||||
		.INIT_D    (INIT_D    ),
 | 
							.INIT_D    (INIT_D    ),
 | 
				
			||||||
		.INIT_E    (INIT_E    ),
 | 
							.INIT_E    (INIT_E    ),
 | 
				
			||||||
		.INIT_F    (INIT_F    )
 | 
							.INIT_F    (INIT_F    ),
 | 
				
			||||||
 | 
							.INIT_FILE (INIT_FILE )
 | 
				
			||||||
	) RAM (
 | 
						) RAM (
 | 
				
			||||||
		.RDATA(RDATA),
 | 
							.RDATA(RDATA),
 | 
				
			||||||
		.RCLK (RCLK ),
 | 
							.RCLK (RCLK ),
 | 
				
			||||||
| 
						 | 
					@ -628,6 +639,8 @@ module SB_RAM40_4KNRNW (
 | 
				
			||||||
	parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
						parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
	parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
						parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parameter INIT_FILE = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SB_RAM40_4K #(
 | 
						SB_RAM40_4K #(
 | 
				
			||||||
		.WRITE_MODE(WRITE_MODE),
 | 
							.WRITE_MODE(WRITE_MODE),
 | 
				
			||||||
		.READ_MODE (READ_MODE ),
 | 
							.READ_MODE (READ_MODE ),
 | 
				
			||||||
| 
						 | 
					@ -646,7 +659,8 @@ module SB_RAM40_4KNRNW (
 | 
				
			||||||
		.INIT_C    (INIT_C    ),
 | 
							.INIT_C    (INIT_C    ),
 | 
				
			||||||
		.INIT_D    (INIT_D    ),
 | 
							.INIT_D    (INIT_D    ),
 | 
				
			||||||
		.INIT_E    (INIT_E    ),
 | 
							.INIT_E    (INIT_E    ),
 | 
				
			||||||
		.INIT_F    (INIT_F    )
 | 
							.INIT_F    (INIT_F    ),
 | 
				
			||||||
 | 
							.INIT_FILE (INIT_FILE )
 | 
				
			||||||
	) RAM (
 | 
						) RAM (
 | 
				
			||||||
		.RDATA(RDATA),
 | 
							.RDATA(RDATA),
 | 
				
			||||||
		.RCLK (~RCLKN),
 | 
							.RCLK (~RCLKN),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										159
									
								
								techlibs/ice40/ice40_braminit.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								techlibs/ice40/ice40_braminit.cc
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,159 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  yosys -- Yosys Open SYnthesis Suite
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 | 
					 *  purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 *  copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
				
			||||||
 | 
					 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
				
			||||||
 | 
					 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "kernel/yosys.h"
 | 
				
			||||||
 | 
					#include "kernel/sigtools.h"
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <bitset>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					USING_YOSYS_NAMESPACE
 | 
				
			||||||
 | 
					PRIVATE_NAMESPACE_BEGIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void run_ice40_braminit(Module *module)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for (auto cell : module->selected_cells())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							uint16_t mem[256];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Only consider cells we're interested in */
 | 
				
			||||||
 | 
							if (cell->type != "\\SB_RAM40_4K" &&
 | 
				
			||||||
 | 
							    cell->type != "\\SB_RAM40_4KNR" &&
 | 
				
			||||||
 | 
							    cell->type != "\\SB_RAM40_4KNW" &&
 | 
				
			||||||
 | 
							    cell->type != "\\SB_RAM40_4KNRNW")
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (!cell->hasParam("\\INIT_FILE"))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							std::string init_file = cell->getParam("\\INIT_FILE").decode_string();
 | 
				
			||||||
 | 
							cell->unsetParam("\\INIT_FILE");
 | 
				
			||||||
 | 
							if (init_file == "")
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Open file */
 | 
				
			||||||
 | 
							log("Processing %s : %s\n", RTLIL::id2cstr(cell->name), init_file.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							std::ifstream f;
 | 
				
			||||||
 | 
							f.open(init_file.c_str());
 | 
				
			||||||
 | 
							if (f.fail()) {
 | 
				
			||||||
 | 
								log("Can not open file `%s`.\n", init_file.c_str());
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Defaults to 0 */
 | 
				
			||||||
 | 
							memset(mem, 0x00, sizeof(mem));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Process each line */
 | 
				
			||||||
 | 
							bool in_comment = false;
 | 
				
			||||||
 | 
							int cursor = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							while (!f.eof())
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								std::string line, token;
 | 
				
			||||||
 | 
								std::getline(f, line);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for (int i = 0; i < GetSize(line); i++)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (in_comment && line.substr(i, 2) == "*/") {
 | 
				
			||||||
 | 
										line[i] = ' ';
 | 
				
			||||||
 | 
										line[i+1] = ' ';
 | 
				
			||||||
 | 
										in_comment = false;
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if (!in_comment && line.substr(i, 2) == "/*")
 | 
				
			||||||
 | 
										in_comment = true;
 | 
				
			||||||
 | 
									if (in_comment)
 | 
				
			||||||
 | 
										line[i] = ' ';
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								while (1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									bool set_cursor = false;
 | 
				
			||||||
 | 
									long value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									token = next_token(line, " \t\r\n");
 | 
				
			||||||
 | 
									if (token.empty() || token.substr(0, 2) == "//")
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (token[0] == '@') {
 | 
				
			||||||
 | 
										token = token.substr(1);
 | 
				
			||||||
 | 
										set_cursor = true;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									const char *nptr = token.c_str();
 | 
				
			||||||
 | 
									char *endptr;
 | 
				
			||||||
 | 
									value = strtol(nptr, &endptr, 16);
 | 
				
			||||||
 | 
									if (!*nptr || *endptr) {
 | 
				
			||||||
 | 
										log("Can not parse %s `%s` for %s.\n",
 | 
				
			||||||
 | 
											set_cursor ? "address" : "value",
 | 
				
			||||||
 | 
											nptr, token.c_str()
 | 
				
			||||||
 | 
										);
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (set_cursor)
 | 
				
			||||||
 | 
										cursor = value;
 | 
				
			||||||
 | 
									else if (cursor >= 0 && cursor < 256)
 | 
				
			||||||
 | 
										mem[cursor++] = value;
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										log("Attempt to initialize non existent address %d\n", cursor);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Set attributes */
 | 
				
			||||||
 | 
							const char *hex = "0123456789ABCDEF";
 | 
				
			||||||
 | 
							for (int i=0; i<16; i++) {
 | 
				
			||||||
 | 
								std::string val = "";
 | 
				
			||||||
 | 
								for (int j=15; j>=0; j--)
 | 
				
			||||||
 | 
									val += std::bitset<16>(mem[i*16+j]).to_string();
 | 
				
			||||||
 | 
								cell->setParam("\\INIT_" + std::string(1, hex[i]), RTLIL::Const::from_string(val));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Ice40BRAMInitPass : public Pass {
 | 
				
			||||||
 | 
						Ice40BRAMInitPass() : Pass("ice40_braminit", "iCE40: perform SB_RAM40_4K initialization from file") { }
 | 
				
			||||||
 | 
						void help() YS_OVERRIDE
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | 
				
			||||||
 | 
							log("\n");
 | 
				
			||||||
 | 
							log("    ice40_braminit\n");
 | 
				
			||||||
 | 
							log("\n");
 | 
				
			||||||
 | 
							log("This command processes all SB_RAM40_4K blocks with a non-empty INIT_FILE\n");
 | 
				
			||||||
 | 
							log("parameter and converts it inti the required INIT_x attributes\n");
 | 
				
			||||||
 | 
							log("\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							log_header(design, "Executing ICE40_BRAMINIT pass.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							size_t argidx;
 | 
				
			||||||
 | 
							for (argidx = 1; argidx < args.size(); argidx++) {
 | 
				
			||||||
 | 
								// if (args[argidx] == "-???") {
 | 
				
			||||||
 | 
								//  continue;
 | 
				
			||||||
 | 
								// }
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							extra_args(args, argidx, design);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (auto module : design->selected_modules())
 | 
				
			||||||
 | 
								run_ice40_braminit(module);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					} Ice40BRAMInitPass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PRIVATE_NAMESPACE_END
 | 
				
			||||||
| 
						 | 
					@ -257,6 +257,7 @@ struct SynthIce40Pass : public ScriptPass
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			run("memory_bram -rules +/ice40/brams.txt");
 | 
								run("memory_bram -rules +/ice40/brams.txt");
 | 
				
			||||||
			run("techmap -map +/ice40/brams_map.v");
 | 
								run("techmap -map +/ice40/brams_map.v");
 | 
				
			||||||
 | 
								run("ice40_braminit");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label("map"))
 | 
							if (check_label("map"))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue