Skip to content

Commit

Permalink
xc2bit: Fix bug with 32A ZIA encoding
Browse files Browse the repository at this point in the history
The much earlier fix for the larger macrocell devices was causing the
32-macrocell ZIA bits to get mirrored. Also, for the sake of
consistency, replace the 32-macrocell ZIA encode/decode with a pattern
match rather than explicitly setting mux bits
ArcaneNibble committed Jun 12, 2017
1 parent 03e0c4b commit 31d97c2
Showing 1 changed file with 49 additions and 55 deletions.
104 changes: 49 additions & 55 deletions src/xc2bit/src/zia.rs
Original file line number Diff line number Diff line change
@@ -9154,80 +9154,74 @@ pub static ZIA_MAP_512: [[XC2ZIAInput; 78]; INPUTS_PER_ANDTERM] = [
XC2ZIAInput::IBuf{ibuf: 0}],
];

const T: bool = true;
const F: bool = false;

/// Internal function that reads a piece of the ZIA corresponding to one FB and one row
pub fn read_32_zia_fb_row_logical(fuses: &[bool], block_idx: usize, row_idx: usize)
-> Result<XC2ZIARowPiece, &'static str> {

let mut zia_row_fuses = [false; 8];

for i in 0..8 {
zia_row_fuses[7 - i] = fuses[block_idx + row_idx * 8 + i];
}

// 7th bit is active-high unlike the rest
zia_row_fuses[7] = !zia_row_fuses[7];

let mut active_bit = 8;
for i in 0..8 {
// active low
if !zia_row_fuses[i] {
if active_bit != 8 {
return Err("multiple ZIA inputs selected!");
}

active_bit = i;
}
}
// This is an ugly workaround for the lack of stable slice patterns
let zia_row_fuses = (
fuses[block_idx + row_idx * 8 + 0],
fuses[block_idx + row_idx * 8 + 1],
fuses[block_idx + row_idx * 8 + 2],
fuses[block_idx + row_idx * 8 + 3],
fuses[block_idx + row_idx * 8 + 4],
fuses[block_idx + row_idx * 8 + 5],
fuses[block_idx + row_idx * 8 + 6],
fuses[block_idx + row_idx * 8 + 7],
);

if active_bit == 8 {
// FIXME: Is this an error?
return Err("no ZIA inputs selected!");
}
let selected_input = match zia_row_fuses {
(F, T, T, T, T, T, T, F) => ZIA_MAP_32[row_idx][0],
(F, T, T, T, T, T, F, T) => ZIA_MAP_32[row_idx][1],
(F, T, T, T, T, F, T, T) => ZIA_MAP_32[row_idx][2],
(F, T, T, T, F, T, T, T) => ZIA_MAP_32[row_idx][3],
(F, T, T, F, T, T, T, T) => ZIA_MAP_32[row_idx][4],
(F, T, F, T, T, T, T, T) => ZIA_MAP_32[row_idx][5],
(T, T, T, T, T, T, T, T) => XC2ZIAInput::One,
(F, F, T, T, T, T, T, T) => XC2ZIAInput::Zero,
_ => return Err("unknown ZIA input choice"),
};

Ok(XC2ZIARowPiece {
selected: if active_bit == 6 {
XC2ZIAInput::Zero
} else if active_bit == 7 {
XC2ZIAInput::One
} else {
ZIA_MAP_32[row_idx][active_bit]
}
selected: selected_input
})
}

/// Internal function that takes a ZIA row and choice and returns the bit encoding for it
pub fn encode_32_zia_choice(row: u32, choice: XC2ZIAInput) -> Option<[bool; 8]> {
if choice == XC2ZIAInput::One {
Some([true, true, true, true, true, true, true, true])
Some([T, T, T, T, T, T, T, T])
} else if choice == XC2ZIAInput::Zero {
Some([true, true, true, true, true, true, false, false])
Some([F, F, T, T, T, T, T, T])
} else {
let mut ret = [true; 8];
// This bit is active-high unlike the rest
ret[7] = false;

let mut found_bit = 8;
let mut found_bit = ZIA_MAP_32[0].len();
for i in 0..ZIA_MAP_32[row as usize].len() {
if choice == ZIA_MAP_32[row as usize][i] {
found_bit = i;
break;
}
}

if found_bit == 8 {
if found_bit == ZIA_MAP_32[0].len() {
// Didn't find it
return None;
}

ret[found_bit] = false;

Some(ret)
match found_bit {
0 => Some([F, T, T, T, T, T, T, F]),
1 => Some([F, T, T, T, T, T, F, T]),
2 => Some([F, T, T, T, T, F, T, T]),
3 => Some([F, T, T, T, F, T, T, T]),
4 => Some([F, T, T, F, T, T, T, T]),
5 => Some([F, T, F, T, T, T, T, T]),
_ => unreachable!(),
}
}
}

const T: bool = true;
const F: bool = false;

/// Internal function that reads a piece of the ZIA corresponding to one FB and one row
pub fn read_64_zia_fb_row_logical(fuses: &[bool], block_idx: usize, row_idx: usize)
-> Result<XC2ZIARowPiece, &'static str> {
@@ -9284,15 +9278,15 @@ pub fn encode_64_zia_choice(row: u32, choice: XC2ZIAInput) -> Option<[bool; 16]>
// TODO: This one isn't certain
Some([T, T, T, T, T, T, T, F, F, T, T, T, T, T, T, T])
} else {
let mut found_bit = 12;
let mut found_bit = ZIA_MAP_64[0].len();
for i in 0..ZIA_MAP_64[row as usize].len() {
if choice == ZIA_MAP_64[row as usize][i] {
found_bit = i;
break;
}
}

if found_bit == 12 {
if found_bit == ZIA_MAP_64[0].len() {
// Didn't find it
return None;
}
@@ -9393,15 +9387,15 @@ pub fn encode_128_zia_choice(row: u32, choice: XC2ZIAInput) -> Option<[bool; 28]
// TODO: This one isn't certain
Some([T, T, T, T, T, T, T, T, F, F, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T])
} else {
let mut found_bit = 22;
let mut found_bit = ZIA_MAP_128[0].len();
for i in 0..ZIA_MAP_128[row as usize].len() {
if choice == ZIA_MAP_128[row as usize][i] {
found_bit = i;
break;
}
}

if found_bit == 22 {
if found_bit == ZIA_MAP_128[0].len() {
// Didn't find it
return None;
}
@@ -9550,15 +9544,15 @@ pub fn encode_256_zia_choice(row: u32, choice: XC2ZIAInput) -> Option<[bool; 48]
// TODO: This one isn't certain
Some([T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, F, T, T, T, T, T, T])
} else {
let mut found_bit = 40;
let mut found_bit = ZIA_MAP_256[0].len();
for i in 0..ZIA_MAP_256[row as usize].len() {
if choice == ZIA_MAP_256[row as usize][i] {
found_bit = i;
break;
}
}

if found_bit == 40 {
if found_bit == ZIA_MAP_256[0].len() {
// Didn't find it
return None;
}
@@ -9773,15 +9767,15 @@ pub fn encode_384_zia_choice(row: u32, choice: XC2ZIAInput) -> Option<[bool; 74]
// TODO: This one isn't certain
Some([T, F, F, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T])
} else {
let mut found_bit = 62;
let mut found_bit = ZIA_MAP_384[0].len();
for i in 0..ZIA_MAP_384[row as usize].len() {
if choice == ZIA_MAP_384[row as usize][i] {
found_bit = i;
break;
}
}

if found_bit == 62 {
if found_bit == ZIA_MAP_384[0].len() {
// Didn't find it
return None;
}
@@ -10048,15 +10042,15 @@ pub fn encode_512_zia_choice(row: u32, choice: XC2ZIAInput) -> Option<[bool; 88]
// TODO: This one isn't certain
Some([T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, F, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T])
} else {
let mut found_bit = 78;
let mut found_bit = ZIA_MAP_512[0].len();
for i in 0..ZIA_MAP_512[row as usize].len() {
if choice == ZIA_MAP_512[row as usize][i] {
found_bit = i;
break;
}
}

if found_bit == 78 {
if found_bit == ZIA_MAP_512[0].len() {
// Didn't find it
return None;
}

0 comments on commit 31d97c2

Please sign in to comment.