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: 39959788130b
Choose a base ref
...
head repository: azonenberg/openfpga
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 73a1180e099e
Choose a head ref
  • 2 commits
  • 4 files changed
  • 1 contributor

Commits on Jun 20, 2017

  1. Copy the full SHA
    78cf6ff View commit details
  2. Copy the full SHA
    73a1180 View commit details
Showing with 275 additions and 107 deletions.
  1. +1 −1 hdl/xc2c-model/XC2CAndArray.v
  2. +177 −0 hdl/xc2c-model/XC2CBitstream.v
  3. +55 −105 hdl/xc2c-model/XC2CDevice.v
  4. +42 −1 hdl/xc2c-model/{XC2CFunctionBlock.v → XC2COrArray.v}
2 changes: 1 addition & 1 deletion hdl/xc2c-model/XC2CAndArray.v
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ module XC2CAndArray(zia_in, config_bits, pterm_out);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The actual AND array

//Higher value is X, lower is !X
//Higher value is !X, lower is X
always @(*) begin
for(nterm=0; nterm<56; nterm = nterm+1) begin
pterm_out[nterm] = 1; //default if no terms selected
177 changes: 177 additions & 0 deletions hdl/xc2c-model/XC2CBitstream.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
`default_nettype none
/***********************************************************************************************************************
* Copyright (C) 2016-2017 Andrew Zonenberg and contributors *
* *
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General *
* Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for *
* more details. *
* *
* You should have received a copy of the GNU Lesser General Public License along with this program; if not, you may *
* find one here: *
* https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt *
* or you may search the http://www.gnu.org website for the version 2.1 license, or you may write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
**********************************************************************************************************************/

/**
@brief Bitstream memory and read/write logic, plus parsing to shuffle it off to various peripherals
*/
module XC2CBitstream(
jtag_tck,
config_erase,
config_read_en, config_read_addr, config_read_data,
config_write_en, config_write_addr, config_write_data,
left_zia_config, right_zia_config,
left_and_config, right_and_config,
left_or_config, right_or_config
);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// I/O declarations

parameter ADDR_BITS = 0;
parameter MEM_DEPTH = 0;
parameter SHREG_WIDTH = 0;

input wire jtag_tck;

input wire config_erase;

input wire config_read_en;
input wire[ADDR_BITS-1:0] config_read_addr;
output reg[SHREG_WIDTH-1:0] config_read_data = 0;

input wire config_write_en;
input wire[ADDR_BITS-1:0] config_write_addr;
input wire[SHREG_WIDTH-1:0] config_write_data;

output reg[40*8-1:0] left_zia_config;
output reg[40*8-1:0] right_zia_config;

output reg[80*56-1:0] left_and_config;
output reg[80*56-1:0] right_and_config;

output reg[16*56-1:0] left_or_config;
output reg[16*56-1:0] right_or_config;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The SRAM copy of the config bitstream (directly drives device behavior)

reg[SHREG_WIDTH-1:0] ram_bitstream[MEM_DEPTH-1:0];

/*
Row configuration, left to right:
1 259 Transfer bit (ignored)
9 258:250 FB2 macrocells
112 249:138 FB2 PLA
16 137:122 ZIA (interleaved)
112 121:10 FB1 PLA
9 9:1 FB1 macrocells
1 0 Transfer bit (ignored)
*/

integer row;
initial begin
for(row=0; row<MEM_DEPTH; row=row+1)
ram_bitstream[row] <= {SHREG_WIDTH{1'b1}}; //copied from blank EEPROM = all 1s
end

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The EEPROM copy of the config bitstream (used to configure ram_bitstream at startup)

//TODO

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// JTAG access

//Read/write the EEPROM
//TODO: add read enable?
always @(posedge jtag_tck) begin

if(config_read_en)
config_read_data <= ram_bitstream[config_read_addr];

if(config_write_en)
ram_bitstream[config_write_addr] <= config_write_data;

//Wipe the config memory
//TODO: go multicycle?
//If we go multicycle, how do we handle this with no clock? Real chip is self-timed internally
if(config_erase) begin
for(row=0; row<MEM_DEPTH; row=row+1)
ram_bitstream[row] <= {SHREG_WIDTH{1'b1}};
end

end

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Shuffle the bitstream out to various IP blocks

integer nbit;
integer nterm;
integer toprow;

always @(*) begin
for(row=0; row<48; row=row+1) begin

toprow = row - 8;

//Rows 0..19: MC-AND-ZIA-AND-MC
//Rows 20...27: MC-OR--GLB-OR--MC
//Rows 28..47: MC-AND-ZIA-AND-MC

//The ZIA is bits 137:122
//MSB is FB1, next is FB2.
//We have stuff at the top and bottom of array, with global config in the middle
if(row > 27) begin
for(nbit=0; nbit<8; nbit=nbit+1) begin
right_zia_config[toprow*8 + nbit] <= ram_bitstream[toprow][123 + nbit*2];
left_zia_config[toprow*8 + nbit] <= ram_bitstream[toprow][122 + nbit*2];
end
end
else if(row < 20) begin
for(nbit=0; nbit<8; nbit=nbit+1) begin
right_zia_config[row*8 + nbit] <= ram_bitstream[row][123 + nbit*2];
left_zia_config[row*8 + nbit] <= ram_bitstream[row][122 + nbit*2];
end
end

//We have PLA AND stuff at the top and bottom of array, with OR array in the middle
//Each row is two bits from PT0, two from PT1, two from PT2, etc
//Right side: 249:138 (mirrored)
//Left side: 121:10
if(row > 27) begin
for(nterm=0; nterm<56; nterm=nterm+1) begin
right_and_config[nterm*80 + toprow*2 + 0] <= ram_bitstream[toprow][249 - nterm*2 - 1];
right_and_config[nterm*80 + toprow*2 + 1] <= ram_bitstream[toprow][249 - nterm*2 - 0];

left_and_config[nterm*80 + toprow*2 + 0] <= ram_bitstream[toprow][10 + nterm*2 + 0];
left_and_config[nterm*80 + toprow*2 + 1] <= ram_bitstream[toprow][10 + nterm*2 + 1];
end
end

else if(row < 20) begin
for(nterm=0; nterm<56; nterm=nterm+1) begin
right_and_config[nterm*80 + row*2 + 0] <= ram_bitstream[row][249 - nterm*2 - 1];
right_and_config[nterm*80 + row*2 + 1] <= ram_bitstream[row][249 - nterm*2 - 0];

left_and_config[nterm*80 + row*2 + 0] <= ram_bitstream[row][10 + nterm*2 + 0];
left_and_config[nterm*80 + row*2 + 1] <= ram_bitstream[row][10 + nterm*2 + 1];
end
end

//PLA OR array
if( (row >= 20) && (row <= 27) ) begin
//TODO
end

end

//TODO: read row 48 (SEC/done) and 49 (usercode)
end

endmodule
160 changes: 55 additions & 105 deletions hdl/xc2c-model/XC2CDevice.v
Original file line number Diff line number Diff line change
@@ -115,64 +115,54 @@ module XC2CDevice(
input wire[MACROCELLS-1:0] iob_in;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The SRAM copy of the config bitstream (directly drives device behavior)

reg[SHREG_WIDTH-1:0] ram_bitstream[MEM_DEPTH-1:0];

/*
Row configuration, left to right:
1 259 Transfer bit (ignored)
9 258:250 FB2 macrocells
112 249:138 FB2 PLA
16 137:122 ZIA (interleaved)
112 121:10 FB1 PLA
9 9:1 FB1 macrocells
1 0 Transfer bit (ignored)
*/

integer row;
initial begin
for(row=0; row<MEM_DEPTH; row=row+1)
ram_bitstream[row] <= {SHREG_WIDTH{1'b1}}; //copied from blank EEPROM = all 1s
end

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The EEPROM copy of the config bitstream (used to configure ram_bitstream at startup)

//TODO

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// JTAG stuff
// The bitstream

wire config_erase;

wire config_read_en;
wire[ADDR_BITS-1:0] config_read_addr;
reg[SHREG_WIDTH-1:0] config_read_data = 0;
wire[SHREG_WIDTH-1:0] config_read_data;

wire config_write_en;
wire[ADDR_BITS-1:0] config_write_addr;
wire[SHREG_WIDTH-1:0] config_write_data;

//Read/write the EEPROM
//TODO: add read enable?
always @(posedge jtag_tck) begin
wire[40*8-1:0] left_zia_config;
wire[40*8-1:0] right_zia_config;

if(config_read_en)
config_read_data <= ram_bitstream[config_read_addr];
wire[80*56-1:0] left_and_config;
wire[80*56-1:0] right_and_config;

if(config_write_en)
ram_bitstream[config_write_addr] <= config_write_data;
wire[16*56-1:0] left_or_config;
wire[16*56-1:0] right_or_config;

//Wipe the config memory
//TODO: pipeline this or are we OK in one cycle?
//If we go multicycle, how do we handle this with no clock? Real chip is self-timed internally
if(config_erase) begin
for(row=0; row<MEM_DEPTH; row=row+1)
ram_bitstream[row] <= {SHREG_WIDTH{1'b1}};
end
XC2CBitstream #(
.ADDR_BITS(ADDR_BITS),
.MEM_DEPTH(MEM_DEPTH),
.SHREG_WIDTH(SHREG_WIDTH)
) bitstream (
.jtag_tck(jtag_tck),

end
.config_erase(config_erase),

.config_read_en(config_read_en),
.config_read_addr(config_read_addr),
.config_read_data(config_read_data),

.config_write_en(config_write_en),
.config_write_addr(config_write_addr),
.config_write_data(config_write_data),

.left_zia_config(left_zia_config),
.left_and_config(left_and_config),
.left_or_config(left_or_config),
.right_zia_config(right_zia_config),
.right_and_config(right_and_config),
.right_or_config(right_or_config)
);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The JTAG TAP (for now, basic bitstream config only)

XC2CJTAG #(
.MACROCELLS(MACROCELLS),
@@ -205,7 +195,6 @@ module XC2CDevice(

//Left side (FB2)
wire[39:0] left_zia_out;
reg[40*8-1:0] left_zia_config;
XC2CZIA #(
.MACROCELLS(MACROCELLS)
) left_zia (
@@ -218,7 +207,6 @@ module XC2CDevice(

//Right side (FB1)
wire[39:0] right_zia_out;
reg[40*8-1:0] right_zia_config;
XC2CZIA #(
.MACROCELLS(MACROCELLS)
) right_zia (
@@ -229,36 +217,9 @@ module XC2CDevice(
.config_bits(right_zia_config)
);

//Hook up the config bits
integer nbit;
always @(*) begin
for(row=0; row<40; row=row+1) begin

//The ZIA is bits 137:122
//MSB is FB1, next is FB2.
//We have stuff at the top and bottom of array, with global config in the middle
if(row >= 20) begin
for(nbit=0; nbit<8; nbit=nbit+1) begin
right_zia_config[row*8 + nbit] <= ram_bitstream[row-8][123 + nbit*2];
left_zia_config[row*8 + nbit] <= ram_bitstream[row-8][122 + nbit*2];
end
end
else begin
for(nbit=0; nbit<8; nbit=nbit+1) begin
right_zia_config[row*8 + nbit] <= ram_bitstream[row][123 + nbit*2];
left_zia_config[row*8 + nbit] <= ram_bitstream[row][122 + nbit*2];
end
end

end
end

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PLA AND array

reg[80*56-1:0] left_and_config;
reg[80*56-1:0] right_and_config;

wire[55:0] left_pterms;
wire[55:0] right_pterms;

@@ -276,40 +237,25 @@ module XC2CDevice(
.pterm_out(right_pterms)
);

//Hook up the config bits
integer nterm;
always @(*) begin

for(row=0; row<40; row=row+1) begin

//We have stuff at the top and bottom of array, with OR array in the middle
//Each row is two bits from PT0, two from PT1, two from PT2, etc

//Right side: 249:138 (mirrored)
//Left side: 121:10
if(row >= 20) begin
for(nterm=0; nterm<56; nterm=nterm+1) begin
right_and_config[nterm*80 + row*2 + 0] <= ram_bitstream[row-8][249 - nterm*2 - 1];
right_and_config[nterm*80 + row*2 + 1] <= ram_bitstream[row-8][249 - nterm*2 - 0];

left_and_config[nterm*80 + row*2 + 0] <= ram_bitstream[row-8][10 + nterm*2 + 0];
left_and_config[nterm*80 + row*2 + 1] <= ram_bitstream[row-8][10 + nterm*2 + 1];
end
end

else begin
for(nterm=0; nterm<56; nterm=nterm+1) begin
right_and_config[nterm*80 + row*2 + 0] <= ram_bitstream[row][249 - nterm*2 - 1];
right_and_config[nterm*80 + row*2 + 1] <= ram_bitstream[row][249 - nterm*2 - 0];
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PLA OR array

left_and_config[nterm*80 + row*2 + 0] <= ram_bitstream[row][10 + nterm*2 + 0];
left_and_config[nterm*80 + row*2 + 1] <= ram_bitstream[row][10 + nterm*2 + 1];
end
end
wire[15:0] left_orterms;
wire[15:0] right_orterms;

end
//FB2
XC2COrArray left_pla_or(
.pterms_in(left_pterms),
.config_bits(left_or_config),
.or_out(left_orterms)
);

end
//FB1
XC2COrArray right_pla_or(
.pterms_in(right_pterms),
.config_bits(right_or_config),
.or_out(right_orterms)
);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Debug stuff
@@ -322,7 +268,11 @@ module XC2CDevice(
//Drive all unused outputs to 0, then hook up our outputs
//Should be X, !X, X, X
assign iob_out[31:7] = 25'h0;
assign iob_out[6:3] = {right_pterms[19], right_pterms[22], right_pterms[25], right_pterms[28]};
//assign iob_out[6:3] = {right_pterms[19], right_pterms[22], right_pterms[25], right_pterms[28]};
assign iob_out[6] = ^right_pterms;
assign iob_out[5] = ^left_pterms;
assign iob_out[4] = ^right_orterms;
assign iob_out[3] = ^left_orterms;
assign iob_out[2:0] = 3'h0;

endmodule
Original file line number Diff line number Diff line change
@@ -16,5 +16,46 @@
* or you may search the http://www.gnu.org website for the version 2.1 license, or you may write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
**********************************************************************************************************************/
module XC2CFunctionBlock();
module XC2COrArray(pterms_in, config_bits, or_out);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// No configuration, all OR arrays are the same.
// Differences in bitstream ordering, if any, are handled by XC2CDevice

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// I/Os

input wire[55:0] pterms_in;
input wire[16*56 - 1 : 0] config_bits;
output reg[15:0] or_out;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Shuffle the config bits back to their proper 2D form

integer nout;
integer nterm;

reg[55:0] or_config[15:0];
always @(*) begin
for(nterm=0; nterm<56; nterm=nterm+1) begin
for(nout=0; nout<16; nout=nout + 1)
or_config[nout][nterm] <= config_bits[nout*56 + nterm];
end
end

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The actual OR array

always @(*) begin
for(nout=0; nout<16; nout = nout+1) begin
or_out[nout] = 0; //default if no terms selected

//OR in the PLA outputs
for(nterm=0; nterm<56; nterm=nterm+1) begin
if(!or_config[nout][nterm])
or_out[nout] = or_out[nout] | pterms_in[nterm];
end
end
end

endmodule