/* * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf * * 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 "kernel/utils.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct HierDirtyFlags; static pool reserved_cids; static dict id2cid; static string cid(IdString id) { if (id2cid.count(id) == 0) { string s = id.str(); if (GetSize(s) < 2) log_abort(); if (s[0] == '\\') s = s.substr(1); if ('0' <= s[0] && s[0] <= '9') { s = "_" + s; } for (int i = 0; i < GetSize(s); i++) { if ('0' <= s[i] && s[i] <= '9') continue; if ('A' <= s[i] && s[i] <= 'Z') continue; if ('a' <= s[i] && s[i] <= 'z') continue; s[i] = '_'; } while (reserved_cids.count(s)) s += "_"; reserved_cids.insert(s); id2cid[id] = s; } return id2cid.at(id); } struct HierDirtyFlags { int dirty; Module *module; IdString hiername; HierDirtyFlags *parent; pool dirty_bits; pool dirty_cells; pool sticky_dirty_bits; dict children; string prefix, log_prefix; HierDirtyFlags(Module *module, IdString hiername, HierDirtyFlags *parent, const string &prefix, const string &log_prefix) : dirty(0), module(module), hiername(hiername), parent(parent), prefix(prefix), log_prefix(log_prefix) { for (Cell *cell : module->cells()) { Module *mod = module->design->module(cell->type); if (mod) children[cell->name] = new HierDirtyFlags(mod, cell->name, this, prefix + cid(cell->name) + ".", log_prefix + "." + prefix + log_id(cell->name)); } } ~HierDirtyFlags() { for (auto &child : children) delete child.second; } void set_dirty(SigBit bit) { if (dirty_bits.count(bit)) return; dirty_bits.insert(bit); sticky_dirty_bits.insert(bit); HierDirtyFlags *p = this; while (p != nullptr) { p->dirty++; p = p->parent; } } void unset_dirty(SigBit bit) { if (dirty_bits.count(bit) == 0) return; dirty_bits.erase(bit); HierDirtyFlags *p = this; while (p != nullptr) { p->dirty--; log_assert(p->dirty >= 0); p = p->parent; } } void set_dirty(Cell *cell) { if (dirty_cells.count(cell)) return; dirty_cells.insert(cell); HierDirtyFlags *p = this; while (p != nullptr) { p->dirty++; p = p->parent; } } void unset_dirty(Cell *cell) { if (dirty_cells.count(cell) == 0) return; dirty_cells.erase(cell); HierDirtyFlags *p = this; while (p != nullptr) { p->dirty--; log_assert(p->dirty >= 0); p = p->parent; } } }; struct SimplecWorker { bool verbose = false; int max_uintsize = 32; Design *design; dict sigmaps; vector signal_declarations; pool generated_sigtypes; vector util_declarations; pool generated_utils; vector struct_declarations; pool generated_structs; vector funct_declarations; dict>>> bit2cell; dict>> bit2output; dict> driven_bits; dict topoidx; pool activated_cells; pool reactivated_cells; SimplecWorker(Design *design) : design(design) { } string sigtype(int n) { string struct_name = stringf("signal%d_t", n); if (generated_sigtypes.count(n) == 0) { signal_declarations.push_back(""); signal_declarations.push_back(stringf("#ifndef YOSYS_SIMPLEC_SIGNAL%d_T", n)); signal_declarations.push_back(stringf("#define YOSYS_SIMPLEC_SIGNAL%d_T", n)); signal_declarations.push_back(stringf("typedef struct {")); for (int k = 8; k <= max_uintsize; k = 2*k) if (n <= k && k <= max_uintsize) { signal_declarations.push_back(stringf(" uint%d_t value_%d_0 : %d;", k, n-1, n)); goto end_struct; } for (int k = 0; k < n; k += max_uintsize) { int bits = std::min(max_uintsize, n-k); signal_declarations.push_back(stringf(" uint%d_t value_%d_%d : %d;", max_uintsize, k+bits-1, k, bits)); } end_struct: signal_declarations.push_back(stringf("} signal%d_t;", n)); signal_declarations.push_back(stringf("#endif")); generated_sigtypes.insert(n); } return struct_name; } void util_ifdef_guard(string s) { for (int i = 0; i < GetSize(s); i++) if ('a' <= s[i] && s[i] <= 'z') s[i] -= 'a' - 'A'; util_declarations.push_back(""); util_declarations.push_back(stringf("#ifndef %s", s.c_str())); util_declarations.push_back(stringf("#define %s", s.c_str())); } string util_get_bit(const string &signame, int n, int idx) { if (n == 1 && idx == 0) return signame + ".value_0_0"; string util_name = stringf("yosys_simplec_get_bit_%d_of_%d", idx, n); if (generated_utils.count(util_name) == 0) { util_ifdef_guard(util_name); util_declarations.push_back(stringf("static inline bool %s(const %s *sig)", util_name.c_str(), sigtype(n).c_str())); util_declarations.push_back(stringf("{")); int word_idx = idx / max_uintsize, word_offset = idx % max_uintsize; string value_name = stringf("value_%d_%d", std::min(n-1, (word_idx+1)*max_uintsize-1), word_idx*max_uintsize); util_declarations.push_back(stringf(" return (sig->%s >> %d) & 1;", value_name.c_str(), word_offset)); util_declarations.push_back(stringf("}")); util_declarations.push_back(stringf("#endif")); generated_utils.insert(util_name); } return stringf("%s(&%s)", util_name.c_str(), signame.c_str()); } string util_set_bit(const string &signame, int n, int idx, const string &expr) { if (n == 1 && idx == 0) return stringf(" %s.value_0_0 = %s;", signame.c_str(), expr.c_str()); string util_name = stringf("yosys_simplec_set_bit_%d_of_%d", idx, n); if (generated_utils.count(util_name) == 0) { util_ifdef_guard(util_name); util_declarations.push_back(stringf("static inline void %s(%s *sig, bool value)", util_name.c_str(), sigtype(n).c_str())); util_declarations.push_back(stringf("{")); int word_idx = idx / max_uintsize, word_offset = idx % max_uintsize; string value_name = stringf("value_%d_%d", std::min(n-1, (word_idx+1)*max_uintsize-1), word_idx*max_uintsize); #if 0 util_declarations.push_back(stringf(" if (value)")); util_declarations.push_back(stringf(" sig->%s |= 1UL << %d;", value_name.c_str(), word_offset)); util_declarations.push_back(stringf(" else")); util_declarations.push_back(stringf(" sig->%s &= ~(1UL << %d);", value_name.c_str(), word_offset)); #else util_declarations.push_back(stringf(" sig->%s = (sig->%s & ~((uint%d_t)1 << %d)) | ((uint%d_t)value << %d);", value_name.c_str(), value_name.c_str(), max_uintsize, word_offset, max_uintsize, word_offset)); #endif util_declarations.push_back(stringf("}")); util_declarations.push_back(stringf("#endif")); generated_utils.insert(util_name); } return stringf(" %s(&%s, %s);", util_name.c_str(), signame.c_str(), expr.c_str()); } void create_module_struct(Module *mod) { if (generated_structs.count(mod->name)) return; generated_structs.insert(mod->name); sigmaps[mod].set(mod); for (Wire *w : mod->wires()) { if (w->port_output) for (auto bit : SigSpec(w)) bit2output[mod][sigmaps.at(mod)(bit)].insert(bit); } for (Cell *c : mod->cells()) { for (auto &conn : c->connections()) { if (!c->input(conn.first)) { for (auto bit : sigmaps.at(mod)(conn.second)) driven_bits[mod].insert(bit); continue; } int idx = 0; for (auto bit : sigmaps.at(mod)(conn.second)) bit2cell[mod][bit].insert(tuple(c, conn.first, idx++)); } if (design->module(c->type)) create_module_struct(design->module(c->type)); } TopoSort topo; for (Cell *c : mod->cells()) { topo.node(c->name); for (auto &conn : c->connections()) { if (!c->input(conn.first)) continue; for
/* **************************************************************************

   This program creates a CRC checksum and encodes the file that is named
   in the command line.
   
   Compile with:  gcc encode_crc.c -Wall -o encode_crc

   Author:     Michael Margraf  (michael.margraf@freecom.com)
   Copyright:  Freecom Technology GmbH, Berlin, 2004
               www.freecom.com

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

 ************************************************************************* */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

// *******************************************************************
// CCITT polynom G(x)=x^16+x^12+x^5+1
#define POLYNOM  0x1021

// CRC algorithm with MSB first
int make_crc16(int crc, char new)
{
  int i;
  crc = crc ^ (((int)new) << 8);
  
  for(i=0; i<8; i++) {  // work on 8 bits in "new"
    crc <<= 1;          // MSBs first
    if(crc & 0x10000)  crc ^= POLYNOM;
  }
  return crc & 0xFFFF;
}

// *******************************************************************
// Reads the file "filename" into memory and returns pointer to the buffer.
static char *readfile(char *filename, int *size)
{
	FILE		*fp;
	char		*buffer;
	struct stat	info;
	
	if (stat(filename,&info)!=0)
		return NULL;

	if ((fp=fopen(filename,"r"))==NULL)
		return NULL;

	buffer=NULL;
	for (;;)
	{
		if ((buffer=(char *)malloc(info.st_size+1))==NULL)
			break;

		if (fread(buffer,1,info.st_size,fp)!=info.st_size)
		{
			free(buffer);
			buffer=NULL;
			break;
		}

		buffer[info.st_size]='\0';
		if(size) *size = info.st_size;

		break;
	}

	(void)fclose(fp);

	return buffer;
}


// *******************************************************************
int main(int argc, char** argv)
{
  if(argc < 3) {
    printf("ERROR: Argument missing!\n\n");
    return 1;
  }

  int count;  // size of file in bytes
  char *p, *master = readfile(argv[1], &count);
  if(!master) {
    printf("ERROR: File not found!\n");
    return 1;
  }

  int crc = 0xFFFF, z;

  p = master;
  for(z=0; z<count; z++)
    crc = make_crc16(crc, *(p++));  // calculate CRC
  short crc16 = (short)crc;

	/*
  if(argc > 2) {   // with flag for device recognition ?
    p = argv[2];
    for(z=strlen(p); z>0; z--) {
      crc ^= (int)(*p);
      *(p++) = (char)crc;  // encode device flag
    }
  }
	*/

  p = master;
  for(z=0; z<count; z++) {
    crc ^= (int)(*p);
    *(p++) = (char)crc;  // encode file
  }


  // write encoded file...
  FILE *fp = fopen(argv[2], "w");
  if(!fp) {
    printf("ERROR: File not writeable!\n");
    return 1;
  }

  if(argc > 3) {  // add flag for device recognition ?
    fwrite(argv[3], strlen(argv[3]), sizeof(char), fp);
  }
  else {
    // Device is an FSG, so byte swap (IXP4xx is big endian)
    crc16 = ((crc16 >> 8) & 0xFF) | ((crc16 << 8) & 0xFF00);
  }

  fwrite(&crc16, 1, sizeof(short), fp);     // first write CRC

  fwrite(master, count, sizeof(char), fp);  // write content
  fclose(fp);

  free(master);
  return 0;
}