mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +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/ice40_braminit.o
 | 
			
		||||
OBJS += techlibs/ice40/ice40_ffssr.o
 | 
			
		||||
OBJS += techlibs/ice40/ice40_ffinit.o
 | 
			
		||||
OBJS += techlibs/ice40/ice40_opt.o
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -326,6 +326,8 @@ module SB_RAM40_4K (
 | 
			
		|||
	parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
 | 
			
		||||
	parameter INIT_FILE = "";
 | 
			
		||||
 | 
			
		||||
`ifndef BLACKBOX
 | 
			
		||||
	wire [15:0] WMASK_I;
 | 
			
		||||
	wire [15:0] RMASK_I;
 | 
			
		||||
| 
						 | 
				
			
			@ -408,6 +410,9 @@ module SB_RAM40_4K (
 | 
			
		|||
	reg [15:0] memory [0:255];
 | 
			
		||||
 | 
			
		||||
	initial begin
 | 
			
		||||
		if (INIT_FILE != "")
 | 
			
		||||
			$readmemh(INIT_FILE, memory);
 | 
			
		||||
		else
 | 
			
		||||
			for (i=0; i<16; i=i+1) begin
 | 
			
		||||
`ifdef YOSYS
 | 
			
		||||
				memory[ 0*16 + i] <= INIT_0[16*i +: 16];
 | 
			
		||||
| 
						 | 
				
			
			@ -504,6 +509,8 @@ module SB_RAM40_4KNR (
 | 
			
		|||
	parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
 | 
			
		||||
	parameter INIT_FILE = "";
 | 
			
		||||
 | 
			
		||||
	SB_RAM40_4K #(
 | 
			
		||||
		.WRITE_MODE(WRITE_MODE),
 | 
			
		||||
		.READ_MODE (READ_MODE ),
 | 
			
		||||
| 
						 | 
				
			
			@ -522,7 +529,8 @@ module SB_RAM40_4KNR (
 | 
			
		|||
		.INIT_C    (INIT_C    ),
 | 
			
		||||
		.INIT_D    (INIT_D    ),
 | 
			
		||||
		.INIT_E    (INIT_E    ),
 | 
			
		||||
		.INIT_F    (INIT_F    )
 | 
			
		||||
		.INIT_F    (INIT_F    ),
 | 
			
		||||
		.INIT_FILE (INIT_FILE )
 | 
			
		||||
	) RAM (
 | 
			
		||||
		.RDATA(RDATA),
 | 
			
		||||
		.RCLK (~RCLKN),
 | 
			
		||||
| 
						 | 
				
			
			@ -566,6 +574,8 @@ module SB_RAM40_4KNW (
 | 
			
		|||
	parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
 | 
			
		||||
	parameter INIT_FILE = "";
 | 
			
		||||
 | 
			
		||||
	SB_RAM40_4K #(
 | 
			
		||||
		.WRITE_MODE(WRITE_MODE),
 | 
			
		||||
		.READ_MODE (READ_MODE ),
 | 
			
		||||
| 
						 | 
				
			
			@ -584,7 +594,8 @@ module SB_RAM40_4KNW (
 | 
			
		|||
		.INIT_C    (INIT_C    ),
 | 
			
		||||
		.INIT_D    (INIT_D    ),
 | 
			
		||||
		.INIT_E    (INIT_E    ),
 | 
			
		||||
		.INIT_F    (INIT_F    )
 | 
			
		||||
		.INIT_F    (INIT_F    ),
 | 
			
		||||
		.INIT_FILE (INIT_FILE )
 | 
			
		||||
	) RAM (
 | 
			
		||||
		.RDATA(RDATA),
 | 
			
		||||
		.RCLK (RCLK ),
 | 
			
		||||
| 
						 | 
				
			
			@ -628,6 +639,8 @@ module SB_RAM40_4KNRNW (
 | 
			
		|||
	parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
	parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
 | 
			
		||||
 | 
			
		||||
	parameter INIT_FILE = "";
 | 
			
		||||
 | 
			
		||||
	SB_RAM40_4K #(
 | 
			
		||||
		.WRITE_MODE(WRITE_MODE),
 | 
			
		||||
		.READ_MODE (READ_MODE ),
 | 
			
		||||
| 
						 | 
				
			
			@ -646,7 +659,8 @@ module SB_RAM40_4KNRNW (
 | 
			
		|||
		.INIT_C    (INIT_C    ),
 | 
			
		||||
		.INIT_D    (INIT_D    ),
 | 
			
		||||
		.INIT_E    (INIT_E    ),
 | 
			
		||||
		.INIT_F    (INIT_F    )
 | 
			
		||||
		.INIT_F    (INIT_F    ),
 | 
			
		||||
		.INIT_FILE (INIT_FILE )
 | 
			
		||||
	) RAM (
 | 
			
		||||
		.RDATA(RDATA),
 | 
			
		||||
		.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("techmap -map +/ice40/brams_map.v");
 | 
			
		||||
			run("ice40_braminit");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (check_label("map"))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue