Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: azonenberg/openfpga
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 7ba4c26e1cc2
Choose a base ref
...
head repository: azonenberg/openfpga
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 52114fe3c82d
Choose a head ref
  • 5 commits
  • 7 files changed
  • 1 contributor

Commits on Jun 14, 2017

  1. Copy the full SHA
    aeeb05e View commit details
  2. xc2bit: Initial plumbing for the native "crbit" file format

    crbit files will be arranged in physical fuse addresses rather than .jed
    logical addresses
    ArcaneNibble committed Jun 14, 2017
    Copy the full SHA
    a960f6d View commit details
  3. Copy the full SHA
    a87331a View commit details
  4. Copy the full SHA
    3a51c34 View commit details
  5. Copy the full SHA
    52114fe View commit details
Showing with 612 additions and 124 deletions.
  1. +57 −0 src/xc2bit/src/bin/xc2jed2crbit.rs
  2. +65 −124 src/xc2bit/src/bitstream.rs
  3. +109 −0 src/xc2bit/src/crbit.rs
  4. +196 −0 src/xc2bit/src/fb.rs
  5. +10 −0 src/xc2bit/src/fusemap_logical.rs
  6. +171 −0 src/xc2bit/src/fusemap_physical.rs
  7. +4 −0 src/xc2bit/src/lib.rs
57 changes: 57 additions & 0 deletions src/xc2bit/src/bin/xc2jed2crbit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
Copyright (c) 2016-2017, Robert Ou <rqou@robertou.com> and contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

//! Testing tool that converts a .jed to the internal .crbit format
use std::fs::File;
use std::io::Read;

extern crate xc2bit;
use xc2bit::*;

fn main() {
let args = ::std::env::args().collect::<Vec<_>>();

if args.len() != 2 {
println!("Usage: {} file.jed", args[0]);
::std::process::exit(1);
}

// Read the entire file
let mut f = File::open(&args[1]).expect("failed to open file");
let mut data = Vec::new();
f.read_to_end(&mut data).expect("failed to read data");

let bits_result = read_jed(&data);
let (bits, device_name_option) = bits_result.expect("failed to read jed");
let device_name = device_name_option.expect("missing device name in jed");

let bitstream_result = process_jed(&bits, &device_name);
let bitstream = bitstream_result.expect("failed to process jed");

let fuse_array = bitstream.to_crbit();

fuse_array.write_to_writer(&mut ::std::io::stdout()).expect("failed to print crbit");
}
189 changes: 65 additions & 124 deletions src/xc2bit/src/bitstream.rs
Original file line number Diff line number Diff line change
@@ -31,7 +31,8 @@ use std::io::Write;
use *;
use fb::{read_fb_logical};
use fusemap_logical::{fb_fuse_idx, gck_fuse_idx, gsr_fuse_idx, gts_fuse_idx, global_term_fuse_idx,
total_logical_fuse_count};
total_logical_fuse_count, clock_div_fuse_idx};
use fusemap_physical::{fuse_array_dims};
use iob::{read_small_iob_logical, read_large_iob_logical, read_32_extra_ibuf_logical};
use mc::{write_small_mc_to_jed, write_large_mc_to_jed};
use zia::{zia_get_row_width};
@@ -70,6 +71,18 @@ impl XC2Bitstream {
Ok(())
}

/// Converts the bitstream into a FuseArray object so that it can be written to the native "crbit" format
pub fn to_crbit(&self) -> FuseArray {
let (w, h) = fuse_array_dims(self.bits.device_type());
let mut fuse_array = FuseArray::from_dim(w, h);

fuse_array.dev_name_str = Some(format!("{}-{}-{}", self.bits.device_type(), self.speed_grade, self.package));

self.bits.to_crbit(&mut fuse_array);

fuse_array
}

/// Construct a new blank bitstream of the given part
pub fn blank_bitstream(device: XC2Device, speed_grade: XC2Speed, package: XC2Package)
-> Result<XC2Bitstream, &'static str> {
@@ -358,65 +371,13 @@ impl Default for XC2ClockDiv {
}

/// Internal function to read the clock divider configuration from a 128-macrocell part
fn read_128_clock_div_logical(fuses: &[bool]) -> XC2ClockDiv {
XC2ClockDiv {
delay: !fuses[55323],
enabled: !fuses[55319],
div_ratio: match (fuses[55320], fuses[55321], fuses[55322]) {
(false, false, false) => XC2ClockDivRatio::Div2,
(false, false, true) => XC2ClockDivRatio::Div4,
(false, true, false) => XC2ClockDivRatio::Div6,
(false, true, true) => XC2ClockDivRatio::Div8,
( true, false, false) => XC2ClockDivRatio::Div10,
( true, false, true) => XC2ClockDivRatio::Div12,
( true, true, false) => XC2ClockDivRatio::Div14,
( true, true, true) => XC2ClockDivRatio::Div16,
}
}
}

/// Internal function to read the clock divider configuration from a 256-macrocell part
fn read_256_clock_div_logical(fuses: &[bool]) -> XC2ClockDiv {
XC2ClockDiv {
delay: !fuses[123231],
enabled: !fuses[123227],
div_ratio: match (fuses[123228], fuses[123229], fuses[123230]) {
(false, false, false) => XC2ClockDivRatio::Div2,
(false, false, true) => XC2ClockDivRatio::Div4,
(false, true, false) => XC2ClockDivRatio::Div6,
(false, true, true) => XC2ClockDivRatio::Div8,
( true, false, false) => XC2ClockDivRatio::Div10,
( true, false, true) => XC2ClockDivRatio::Div12,
( true, true, false) => XC2ClockDivRatio::Div14,
( true, true, true) => XC2ClockDivRatio::Div16,
}
}
}
fn read_clock_div_logical(device: XC2Device, fuses: &[bool]) -> XC2ClockDiv {
let clock_fuse_block = clock_div_fuse_idx(device);

/// Internal function to read the clock divider configuration from a 384-macrocell part
fn read_384_clock_div_logical(fuses: &[bool]) -> XC2ClockDiv {
XC2ClockDiv {
delay: !fuses[209335],
enabled: !fuses[209331],
div_ratio: match (fuses[209332], fuses[209333], fuses[209334]) {
(false, false, false) => XC2ClockDivRatio::Div2,
(false, false, true) => XC2ClockDivRatio::Div4,
(false, true, false) => XC2ClockDivRatio::Div6,
(false, true, true) => XC2ClockDivRatio::Div8,
( true, false, false) => XC2ClockDivRatio::Div10,
( true, false, true) => XC2ClockDivRatio::Div12,
( true, true, false) => XC2ClockDivRatio::Div14,
( true, true, true) => XC2ClockDivRatio::Div16,
}
}
}

/// Internal function to read the clock divider configuration from a 512-macrocell part
fn read_512_clock_div_logical(fuses: &[bool]) -> XC2ClockDiv {
XC2ClockDiv {
delay: !fuses[296381],
enabled: !fuses[296377],
div_ratio: match (fuses[296378], fuses[296379], fuses[296380]) {
delay: !fuses[clock_fuse_block + 4],
enabled: !fuses[clock_fuse_block],
div_ratio: match (fuses[clock_fuse_block + 1], fuses[clock_fuse_block + 2], fuses[clock_fuse_block + 3]) {
(false, false, false) => XC2ClockDivRatio::Div2,
(false, false, true) => XC2ClockDivRatio::Div4,
(false, true, false) => XC2ClockDivRatio::Div6,
@@ -618,6 +579,29 @@ impl XC2BitstreamBits {
}
}

pub fn get_clock_div(&self) -> Option<&XC2ClockDiv> {
match self {
&XC2BitstreamBits::XC2C32{..} => None,
&XC2BitstreamBits::XC2C32A{..} => None,
&XC2BitstreamBits::XC2C64{..} => None,
&XC2BitstreamBits::XC2C64A{..} => None,
&XC2BitstreamBits::XC2C128{ref clock_div, ..} => Some(clock_div),
&XC2BitstreamBits::XC2C256{ref clock_div, ..} => Some(clock_div),
&XC2BitstreamBits::XC2C384{ref clock_div, ..} => Some(clock_div),
&XC2BitstreamBits::XC2C512{ref clock_div, ..} => Some(clock_div),
}
}

/// Convert the actual bitstream bits to crbit format
pub fn to_crbit(&self, fuse_array: &mut FuseArray) {
// TODO

// FBs
for i in 0..self.device_type().num_fbs() {
self.get_fb()[i].to_crbit(self.device_type(), i as u32, fuse_array);
}
}

/// Dump a human-readable explanation of the bitstream to the given `writer` object.
pub fn dump_human_readable(&self, writer: &mut Write) -> Result<(), io::Error> {
match self {
@@ -857,68 +841,25 @@ impl XC2BitstreamBits {
if self.get_global_nets().gck_enable[2] {"1"} else {"0"})?;

// Clock divider
match self {
&XC2BitstreamBits::XC2C128 {clock_div, ..} => {
write!(writer, "L055319 {}{}*\n",
if clock_div.enabled {"0"} else {"1"},
match clock_div.div_ratio {
XC2ClockDivRatio::Div2 => "000",
XC2ClockDivRatio::Div4 => "001",
XC2ClockDivRatio::Div6 => "010",
XC2ClockDivRatio::Div8 => "011",
XC2ClockDivRatio::Div10 => "100",
XC2ClockDivRatio::Div12 => "101",
XC2ClockDivRatio::Div14 => "110",
XC2ClockDivRatio::Div16 => "111",
})?;
write!(writer, "L055323 {}*\n", if clock_div.delay {"0"} else {"1"})?;
},
&XC2BitstreamBits::XC2C256 {clock_div, ..} => {
write!(writer, "L123227 {}{}*\n",
if clock_div.enabled {"0"} else {"1"},
match clock_div.div_ratio {
XC2ClockDivRatio::Div2 => "000",
XC2ClockDivRatio::Div4 => "001",
XC2ClockDivRatio::Div6 => "010",
XC2ClockDivRatio::Div8 => "011",
XC2ClockDivRatio::Div10 => "100",
XC2ClockDivRatio::Div12 => "101",
XC2ClockDivRatio::Div14 => "110",
XC2ClockDivRatio::Div16 => "111",
})?;
write!(writer, "L123231 {}*\n", if clock_div.delay {"0"} else {"1"})?;
},
&XC2BitstreamBits::XC2C384 {clock_div, ..} => {
write!(writer, "L209331 {}{}*\n",
if clock_div.enabled {"0"} else {"1"},
match clock_div.div_ratio {
XC2ClockDivRatio::Div2 => "000",
XC2ClockDivRatio::Div4 => "001",
XC2ClockDivRatio::Div6 => "010",
XC2ClockDivRatio::Div8 => "011",
XC2ClockDivRatio::Div10 => "100",
XC2ClockDivRatio::Div12 => "101",
XC2ClockDivRatio::Div14 => "110",
XC2ClockDivRatio::Div16 => "111",
})?;
write!(writer, "L209335 {}*\n", if clock_div.delay {"0"} else {"1"})?;
},
&XC2BitstreamBits::XC2C512 {clock_div, ..} => {
write!(writer, "L296377 {}{}*\n",
if clock_div.enabled {"0"} else {"1"},
match clock_div.div_ratio {
XC2ClockDivRatio::Div2 => "000",
XC2ClockDivRatio::Div4 => "001",
XC2ClockDivRatio::Div6 => "010",
XC2ClockDivRatio::Div8 => "011",
XC2ClockDivRatio::Div10 => "100",
XC2ClockDivRatio::Div12 => "101",
XC2ClockDivRatio::Div14 => "110",
XC2ClockDivRatio::Div16 => "111",
})?;
write!(writer, "L296381 {}*\n", if clock_div.delay {"0"} else {"1"})?;
},
_ => {},
if let Some(clock_div) = self.get_clock_div() {
let clock_fuse_block = clock_div_fuse_idx(self.device_type());

write!(writer, "L{:06} {}{}*\n",
clock_fuse_block,
if clock_div.enabled {"0"} else {"1"},
match clock_div.div_ratio {
XC2ClockDivRatio::Div2 => "000",
XC2ClockDivRatio::Div4 => "001",
XC2ClockDivRatio::Div6 => "010",
XC2ClockDivRatio::Div8 => "011",
XC2ClockDivRatio::Div10 => "100",
XC2ClockDivRatio::Div12 => "101",
XC2ClockDivRatio::Div14 => "110",
XC2ClockDivRatio::Div16 => "111",
})?;
write!(writer, "L{:06} {}*\n",
clock_fuse_block + 4,
if clock_div.delay {"0"} else {"1"})?;
}

// GSR
@@ -1187,7 +1128,7 @@ pub fn read_128_bitstream_logical(fuses: &[bool]) -> Result<XC2BitstreamBits, &'
fb: fb,
iobs: iobs,
global_nets: global_nets,
clock_div: read_128_clock_div_logical(fuses),
clock_div: read_clock_div_logical(XC2Device::XC2C128, fuses),
data_gate: !fuses[55335],
use_vref: !fuses[55340],
ivoltage: [
@@ -1214,7 +1155,7 @@ pub fn read_256_bitstream_logical(fuses: &[bool]) -> Result<XC2BitstreamBits, &'
fb: fb,
iobs: iobs,
global_nets: global_nets,
clock_div: read_256_clock_div_logical(fuses),
clock_div: read_clock_div_logical(XC2Device::XC2C256, fuses),
data_gate: !fuses[123243],
use_vref: !fuses[123248],
ivoltage: [
@@ -1241,7 +1182,7 @@ pub fn read_384_bitstream_logical(fuses: &[bool]) -> Result<XC2BitstreamBits, &'
fb: fb,
iobs: iobs,
global_nets: global_nets,
clock_div: read_384_clock_div_logical(fuses),
clock_div: read_clock_div_logical(XC2Device::XC2C384, fuses),
data_gate: !fuses[209347],
use_vref: !fuses[209356],
ivoltage: [
@@ -1272,7 +1213,7 @@ pub fn read_512_bitstream_logical(fuses: &[bool]) -> Result<XC2BitstreamBits, &'
fb: fb,
iobs: iobs,
global_nets: global_nets,
clock_div: read_512_clock_div_logical(fuses),
clock_div: read_clock_div_logical(XC2Device::XC2C512, fuses),
data_gate: !fuses[296393],
use_vref: !fuses[296402],
ivoltage: [
Loading