/* * 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" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN void aiger_encode(std::ostream &f, int x) { log_assert(x >= 0); while (x & ~0x7f) { f.put((x & 0x7f) | 0x80); x = x >> 7; } f.put(x); } struct AigerWriter { Module *module; bool zinit_mode; SigMap sigmap; dict init_map; pool input_bits, output_bits; dict not_map, ff_map, alias_map; dict> and_map; vector> asserts, assumes; vector> liveness, fairness; pool initstate_bits; vector> aig_gates; vector aig_latchin, aig_latchinit, aig_outputs; int aig_m = 0, aig_i = 0, aig_l = 0, aig_o = 0, aig_a = 0; int aig_b = 0, aig_c = 0, aig_j = 0, aig_f = 0; dict aig_map; dict ordered_outputs; dict ordered_latches; dict init_inputs; int initstate_ff = 0; int mkgate(int a0, int a1) { aig_m++, aig_a++; aig_gates.push_back(a0 > a1 ? make_pair(a0, a1) : make_pair(a1, a0)); return 2*aig_m; } int bit2aig(SigBit bit) { auto it = aig_map.find(bit); if (it != aig_map.end()) { log_assert(it->second >= 0); return it->second; } // NB: Cannot use iterator returned from aig_map.insert() // since this function is called recursively int a = -1; if (not_map.count(bit)) { a = bit2aig(not_map.at(bit)) ^ 1; } else if (and_map.count(bit)) { auto args = and_map.at(bit); int a0 = bit2aig(args.first); int a1 = bit2aig(args.second); a = mkgate(a0, a1); } else if (alias_map.count(bit)) { a = bit2aig(alias_map.at(bit)); } else if (initstate_bits.count(bit)) { a = initstate_ff; } if (bit == State::Sx || bit == State::Sz) log_error("Design contains 'x' or 'z' bits. Use 'setundef' to replace those constants.\n"); log_assert(a >= 0); aig_map[bit] = a; return a; } AigerWriter(Module *module, bool zinit_mode, bool imode, bool omode, bool bmode, bool lmode) : module(module), zinit_mode(zinit_mode), sigmap(module) { pool undriven_bits; pool unused_bits; // promote public wires for (auto wire : module->wires()) if (wire->name[0] == '\\') sigmap.add(wire); // promote input wires for (auto wire : module->wires()) if (wire->port_input) sigmap.add(wire); // promote output wires for (auto wire : module->wires()) if (wire->port_output) sigmap.add(wire); for (auto wire : module->wires()) { if (wire->attributes.count("\\init")) { SigSpec initsig = sigmap(wire); Const initval = wire->attributes.at("\\init"); for (int i = 0; i < GetSize(wire) && i < GetSize(initval); i++) if (initval[i] == State::S0 || initval[i] == State::S1) init_map[initsig[i]] = initval[i] == State::S1; } for (int i = 0; i < GetSize(wire); i++) { SigBit wirebit(wire, i); SigBit bit = sigmap(wirebit); if (bit.wire == nullptr) { if (wire->port_output) { aig_map[wirebit] = (bit == State::S1) ? 1 : 0; output_bits.insert(wirebit); } continue; } undriven_bits.insert(bit); unused_bits.insert(bit); if (wire->port_input) input_bits.insert(bit); if (wire->port_output) { if (bit != wirebit) alias_map[wirebit] = bit; output_bits.insert(wirebit); } } } for (auto bit : input_bits) undriven_bits.erase(bit); for (auto bit : output_bits) unused_bits.erase(bit); for (auto cell : module->cells()) { if (cell->type == "$_NOT_") { SigBit A = sigmap(cell->getPort("\\A").as_bit()); SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); unused_bits.erase(A); undriven_bits.erase(Y); not_map[Y] = A; continue; } if (cell->type.in("$_FF_", "$_DFF_N_", "$_DFF_P_")) { SigBit D = sigmap(cell->getPort("\\D").as_bit()); SigBit Q = sigmap(cell->getPort("\\Q").as_bit()); unused_bits.erase(D); undriven_bits.erase(Q); ff_map[Q] = D; continue; } if (cell->type == "$_AND_") { SigBit A = sigmap(cell->getPort("\\A").as_bit()); SigBit B = sigmap(cell->getPort("\\B").as_bit()); SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); unused_bits.erase(A); unused_bits.erase(B); undriven_bits.erase(Y); and_map[Y] = make_pair(A, B); continue; } if (cell->type == "$initstate") { SigBit Y = sigmap(cell->getPort("\\Y").as_bit()); undriven_bits.erase(Y); initstate_bits.insert(Y); continue; } if (cell->type == "$assert") { SigBit A = sigmap(cell->getPort("\\A").as_bit()); SigBit EN = sigmap(cell->getPort("\\EN").as_bit()); unused_bits.erase(A); unused_bits.erase(EN); asserts.push_back(make_pair(A, EN)); continue; } if (cell->type == "$assume") { SigBit A = sigmap(cell->getPort("\\A").as_bit()); SigBit EN = sigmap(cell->getPort("\\EN").as_bit()); unused_bits.erase(A); unused_bits.erase(EN); assumes.push_back(make_pair(A, EN)); continue; } if (cell->type == "$live") { SigBit A = sigmap(cell->getPort("\\A").as_bit()); SigBit EN = sigmap(cell->getPort("\\EN").as_bit()); unused_bits.erase(A); unused_bits.erase(EN); liveness.push_back(make_pair(A, EN)); continue; } if (cell->type == "$fair") { SigBit A = sigmap(cell->getPort("\\A").as_bit()); SigBit EN = sigmap(cell->getPort("\\EN").as_bit()); unused_bits.erase(A); unused_bits.erase(EN); fairness.push_back(make_pair(A, EN)); continue; } if (cell->type == "$anyconst") { for (auto bit : sigmap(cell->getPort("\\Y"))) { undriven_bits.erase(bit); ff_map[bit] = bit; } continue; } if (cell->type == "$anyseq") { for (auto bit : sigmap(cell->getPort("\\Y"))) { undriven_bits.erase(bit); input_bits.insert(bit); } continue; } log_error("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell)); } for (auto bit : unused_bits) undriven_bits.erase(bit); if (!undriven_bits.empty()) { undriven_bits.sort(); for (auto bit : undriven_bits) { log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit)); input_bits.insert(bit); } log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module)); } init_map.sort(); input_bits.sort(); output_bits.sort(); not_map.sort(); ff_map.sort(); and_map.sort(); aig_map[State::S0] = 0; aig_map[State::S1] = 1; for (auto bit : input_bits) { aig_m++, aig_i++; aig_map[bit] = 2*aig_m; } if (imode && input_bits.empty()) { aig_m++, aig_i++; } if (zinit_mode) { for (auto it : ff_map) { if (init_map.count(it.first)) continue; aig_m++, aig_i++; init_inputs[it.first] = 2*aig_m; } } int fair_live_inputs_cnt = GetSize(liveness); int fair_live_inputs_m = aig_m; aig_m += fair_live_inp
/*
    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include "ch.h"
#include "hal.h"

/*
 * Maximum speed SPI configuration (16MHz, CPHA=0, CPOL=0, MSb first).
 */
static const SPIConfig hs_spicfg = {
  NULL,
  GPIOB,
  12,
  0
};

/*
 * Low speed SPI configuration (256kHz, CPHA=0, CPOL=0, MSb first).
 */
static const SPIConfig ls_spicfg = {
  NULL,
  GPIOB,
  12,
  SPI_CR1_BR_2 | SPI_CR1_BR_1
};

/*
 * SPI TX and RX buffers.
 */
static uint8_t txbuf[512];
static uint8_t rxbuf[512];

/*
 * SPI bus contender 1.
 */
static THD_WORKING_AREA(spi_thread_1_wa, 256);
static THD_FUNCTION(spi_thread_1, p) {

  (void)p;

  chRegSetThreadName("SPI thread 1");
  while (true) {
    spiAcquireBus(&SPID2);              /* Acquire ownership of the bus.    */
    palSetPad(GPIOB, GPIOB_LED4);       /* LED ON.                          */
    spiStart(&SPID2, &hs_spicfg);       /* Setup transfer parameters.       */
    spiSelect(&SPID2);                  /* Slave Select assertion.          */
    spiExchange(&SPID2, 512,
                txbuf, rxbuf);          /* Atomic transfer operations.      */
    spiUnselect(&SPID2);                /* Slave Select de-assertion.       */
    spiReleaseBus(&SPID2);              /* Ownership release.               */
  }
}

/*
 * SPI bus contender 2.
 */
static THD_WORKING_AREA(spi_thread_2_wa, 256);
static THD_FUNCTION(spi_thread_2, p) {

  (void)p;

  chRegSetThreadName("SPI thread 2");
  while (true) {
    spiAcquireBus(&SPID2);              /* Acquire ownership of the bus.    */
    palClearPad(GPIOB, GPIOB_LED4);     /* LED OFF.                         */
    spiStart(&SPID2, &ls_spicfg);       /* Setup transfer parameters.       */
    spiSelect(&SPID2);                  /* Slave Select assertion.          */
    spiExchange(&SPID2, 512,
                txbuf, rxbuf);          /* Atomic transfer operations.      */
    spiUnselect(&SPID2);                /* Slave Select de-assertion.       */
    spiReleaseBus(&SPID2);              /* Ownership release.               */
  }
}

/*
 * Application entry point.
 */
int main(void) {
  unsigned i;

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * SPI1 I/O pins setup.
   */
  palSetPadMode(GPIOB, 12, PAL_MODE_OUTPUT_PUSHPULL |
                           PAL_STM32_OSPEED_HIGHEST);           /* NSS.     */
  palSetPadMode(GPIOB, 13, PAL_MODE_ALTERNATE(5) |
                           PAL_STM32_OSPEED_HIGHEST);           /* SCK.     */
  palSetPadMode(GPIOB, 14, PAL_MODE_ALTERNATE(5));              /* MISO.    */
  palSetPadMode(GPIOB, 15, PAL_MODE_ALTERNATE(5) |
                           PAL_STM32_OSPEED_HIGHEST);           /* MOSI.    */
  palSetPad(GPIOB, 12);

  /*
   * Prepare transmit pattern.
   */
  for (i = 0; i < sizeof(txbuf); i++)
    txbuf[i] = (uint8_t)i;

  /*
   * Starting the transmitter and receiver threads.
   */
  chThdCreateStatic(spi_thread_1_wa, sizeof(spi_thread_1_wa),
                    NORMALPRIO + 1, spi_thread_1, NULL);
  chThdCreateStatic(spi_thread_2_wa, sizeof(spi_thread_2_wa),
                    NORMALPRIO + 1, spi_thread_2, NULL);

  /*
   * Normal main() thread activity, in this demo it does nothing.
   */
  while (true) {
    chThdSleepMilliseconds(500);
  }
  return 0;
}