mirror of
https://github.com/annoyatron255/yosys4gal.git
synced 2024-12-22 10:42:24 +00:00
Add initial GAL22V10 model
This commit is contained in:
parent
fb4ae03c91
commit
41c60bcab6
3
models/.gitignore
vendored
3
models/.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
a.out
|
||||
dump.vcd
|
||||
GAL16V8_reg.bin
|
||||
GAL16V8_reg.hex
|
||||
GAL22V10_reg.hex
|
||||
__temp.bin
|
||||
|
|
163
models/GAL22V10_reg.v
Normal file
163
models/GAL22V10_reg.v
Normal file
|
@ -0,0 +1,163 @@
|
|||
`default_nettype none
|
||||
module GAL22V10_reg (
|
||||
input wire [12:0] in, // Pin {13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, 1 is clk
|
||||
inout wire [9:0] io // Pin {14, 15, 16, 17, 18, 19, 20, 21, 22, 23}
|
||||
);
|
||||
// Read in binary JEDEC file
|
||||
reg [7:0] jed_bin_file [0:740];
|
||||
initial $readmemh("GAL22V10_reg.hex", jed_bin_file);
|
||||
|
||||
// Linearize to a fuse map
|
||||
wire [5891:0] fuses;
|
||||
genvar i, j;
|
||||
generate
|
||||
for (i = 0; i < 736; i = i + 1) begin
|
||||
for (j = 0; j < 8; j = j + 1) begin
|
||||
assign fuses[8*i + j] = jed_bin_file[i + 4][j];
|
||||
end
|
||||
end
|
||||
// Last couple bits
|
||||
for (j = 0; j < 4; j = j + 1) begin
|
||||
assign fuses[8*736 + j] = jed_bin_file[736 + 4][j];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Extract useful fuses
|
||||
wire [9:0] xor_fuses;
|
||||
assign xor_fuses = {fuses[5826], fuses[5824], fuses[5822], fuses[5820], fuses[5818],
|
||||
fuses[5816], fuses[5814], fuses[5812], fuses[5810], fuses[5808]};
|
||||
|
||||
wire [9:0] reg_fuses;
|
||||
assign reg_fuses = {fuses[5827], fuses[5825], fuses[5823], fuses[5821], fuses[5819],
|
||||
fuses[5817], fuses[5815], fuses[5813], fuses[5811], fuses[5809]};
|
||||
|
||||
wire [747:0] sop_fuses [0:9];
|
||||
assign sop_fuses[0] = {352'b0, fuses[439:44]};
|
||||
assign sop_fuses[1] = {264'b0, fuses[923:440]};
|
||||
assign sop_fuses[2] = {176'b0, fuses[1495:924]};
|
||||
assign sop_fuses[3] = {88'b0, fuses[2155:1496]};
|
||||
assign sop_fuses[4] = fuses[2903:2156];
|
||||
assign sop_fuses[5] = fuses[3651:2904];
|
||||
assign sop_fuses[6] = {88'b0, fuses[4311:3652]};
|
||||
assign sop_fuses[7] = {176'b0, fuses[4883:4312]};
|
||||
assign sop_fuses[8] = {264'b0, fuses[5367:4884]};
|
||||
assign sop_fuses[9] = {352'b0, fuses[5763:5368]};
|
||||
|
||||
|
||||
// Interleave in and feedback for SOP inputs
|
||||
wire [9:0] feedback;
|
||||
wire [21:0] interleaved;
|
||||
generate
|
||||
for (i = 0; i < 10; i = i + 1) begin
|
||||
assign interleaved[2*i +: 2] = {feedback[i], in[i]};
|
||||
end
|
||||
assign interleaved[21:20] = {in[11], in[10]};
|
||||
endgenerate
|
||||
|
||||
// Generate GAL elements
|
||||
generate
|
||||
for (i = 0; i < 10; i = i + 1) begin
|
||||
wire one_sop_out, sop_out;
|
||||
|
||||
// 1SOP
|
||||
sop #(
|
||||
.NUM_PRODUCTS(1),
|
||||
.NUM_INPUTS(22)
|
||||
) one_sop_inst (
|
||||
.sop_fuses(sop_fuses[i][43:0]),
|
||||
.in(interleaved),
|
||||
.out(one_sop_out)
|
||||
);
|
||||
|
||||
// SOP
|
||||
sop #(
|
||||
.NUM_PRODUCTS(16),
|
||||
.NUM_INPUTS(22)
|
||||
) sop_inst (
|
||||
.sop_fuses(sop_fuses[i][747:44]),
|
||||
.in(interleaved),
|
||||
.out(sop_out)
|
||||
);
|
||||
|
||||
// OLMC
|
||||
olmc olmc_inst (
|
||||
.xor_fuse(xor_fuses[i]),
|
||||
.reg_fuse(reg_fuses[i]),
|
||||
.sop(sop_out),
|
||||
.one_sop(one_sop_out),
|
||||
.clk(in[0]),
|
||||
.io(io[i]),
|
||||
.feedback(feedback[i])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Simulation printing
|
||||
initial begin
|
||||
#1;
|
||||
$display("XOR: %b, REG: %b", xor_fuses, reg_fuses);
|
||||
$display("Fuses: %x", fuses);
|
||||
|
||||
$display("sop0 %x", sop_fuses[0]);
|
||||
$display("sop1 %x", sop_fuses[1]);
|
||||
$display("sop2 %x", sop_fuses[2]);
|
||||
$display("sop3 %x", sop_fuses[3]);
|
||||
$display("sop4 %x", sop_fuses[4]);
|
||||
$display("sop5 %x", sop_fuses[5]);
|
||||
$display("sop6 %x", sop_fuses[6]);
|
||||
$display("sop7 %x", sop_fuses[7]);
|
||||
$display("sop8 %x", sop_fuses[8]);
|
||||
$display("sop9 %x", sop_fuses[9]);
|
||||
end
|
||||
endmodule
|
||||
|
||||
module sop #(
|
||||
parameter NUM_PRODUCTS = 7,
|
||||
parameter NUM_INPUTS = 16
|
||||
)(
|
||||
input wire [2*NUM_INPUTS*NUM_PRODUCTS-1:0] sop_fuses,
|
||||
input wire [NUM_INPUTS-1:0] in,
|
||||
output reg out
|
||||
);
|
||||
integer i, j;
|
||||
reg match;
|
||||
|
||||
always @ (*) begin
|
||||
out = 0;
|
||||
for (i = 0; i < NUM_PRODUCTS; i = i + 1) begin
|
||||
match = 1;
|
||||
for (j = 0; j < NUM_INPUTS; j = j + 1) begin
|
||||
if (!sop_fuses[2*NUM_INPUTS*i + 2*j + 0] && !in[j]) match = 0;
|
||||
if (!sop_fuses[2*NUM_INPUTS*i + 2*j + 1] && in[j]) match = 0;
|
||||
end
|
||||
if (match) out = 1;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
module olmc (
|
||||
input wire xor_fuse,
|
||||
input wire reg_fuse,
|
||||
|
||||
input wire sop,
|
||||
input wire one_sop,
|
||||
|
||||
input wire clk,
|
||||
|
||||
inout wire io,
|
||||
output wire feedback
|
||||
);
|
||||
// Internal combined SOP output with optional inversion
|
||||
wire out;
|
||||
assign out = sop ^ xor_fuse;
|
||||
|
||||
reg reg_out;
|
||||
always @ (posedge clk) begin
|
||||
reg_out <= out;
|
||||
end
|
||||
|
||||
assign feedback = reg_fuse ? !out : !reg_out ^ xor_fuse;
|
||||
|
||||
assign io = reg_fuse ? (one_sop ? !out : 1'bz) : // Combinational
|
||||
(one_sop ? !reg_out : 1'bz); // Registered
|
||||
endmodule
|
30
models/GAL22V10_reg_tb.v
Normal file
30
models/GAL22V10_reg_tb.v
Normal file
|
@ -0,0 +1,30 @@
|
|||
module GAL22V10_reg_tb(
|
||||
output reg [12:0] in = 13'bx_xxxx_xxxx_xxx1,
|
||||
inout wire [9:0] io
|
||||
);
|
||||
|
||||
GAL22V10_reg GAL22V10_reg_inst (
|
||||
.in(in),
|
||||
.io(io)
|
||||
);
|
||||
|
||||
always #5 in[0] = !in[0];
|
||||
|
||||
initial begin
|
||||
$dumpfile("dump.vcd");
|
||||
$dumpvars(0, GAL22V10_reg_tb);
|
||||
#3;
|
||||
in[12:1] = 12'bxxxx_xxxx_x00x;
|
||||
#10;
|
||||
in[12:1] = 12'bxxxx_xxxx_x01x;
|
||||
#10;
|
||||
in[12:1] = 12'bxxxx_xxxx_x10x;
|
||||
#10;
|
||||
in[12:1] = 12'bxxxx_xxxx_x11x;
|
||||
#10;
|
||||
in[12:1] = 12'bxxxx_xxxx_x00x;
|
||||
#10;
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
12
models/GAL22V10_wrapper.v
Normal file
12
models/GAL22V10_wrapper.v
Normal file
|
@ -0,0 +1,12 @@
|
|||
`default_nettype none
|
||||
module __wrapper (
|
||||
input wire [12:0] __in, // Pin {13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, 1 is clk
|
||||
inout wire [9:0] __io // Pin {14, 15, 16, 17, 18, 19, 20, 21, 22, 23}
|
||||
);
|
||||
|
||||
GAL22V10_reg GAL22V10_reg_inst (
|
||||
.in(__in),
|
||||
.io(__io)
|
||||
);
|
||||
|
||||
endmodule
|
|
@ -11,24 +11,44 @@ set jedec_file [lindex $argv 0]
|
|||
set pcf_file [lindex $argv 1]
|
||||
set verilog_files [lrange $argv 2 end]
|
||||
|
||||
# Convert JEDEC file to hex for Verilog model
|
||||
exec jedutil -convert $jedec_file GAL16V8_reg.bin
|
||||
exec xxd -ps -c 1 GAL16V8_reg.bin GAL16V8_reg.hex
|
||||
# Convert JEDEC file to bin
|
||||
exec jedutil -convert $jedec_file __temp.bin
|
||||
|
||||
# Find chip being used
|
||||
set jedec_bin_size [file size __temp.bin]
|
||||
if {$jedec_bin_size == 279} {
|
||||
set chip GAL16V8
|
||||
set pin_mapping [dict create 1 "clk" 2 "in\[0\]" 3 "in\[1\]" 4 "in\[2\]" 5 "in\[3\]" 6 "in\[4\]" 7 "in\[5\]" 8 "in\[6\]" 9 "in\[7\]" 11 "oe_n" 12 "io\[7\]" 13 "io\[6\]" 14 "io\[5\]" 15 "io\[4\]" 16 "io\[3\]" 17 "io\[2\]" 18 "io\[1\]" 19 "io\[0\]"]
|
||||
} elseif {$jedec_bin_size == 741} {
|
||||
set chip GAL22V10
|
||||
set pin_mapping [dict create 1 "in\[0\]" 2 "in\[1\]" 3 "in\[2\]" 4 "in\[3\]" 5 "in\[4\]" 6 "in\[5\]" 7 "in\[6\]" 8 "in\[7\]" 9 "in\[8\]" 10 "in\[9\]" 11 "in\[10\]" 12 "in\[11\]" 13 "in\[12\]" 14 "io\[9\]" 15 "io\[8\]" 16 "io\[7\]" 17 "io\[6\]" 18 "io\[5\]" 19 "io\[4\]" 20 "io\[3\]" 21 "io\[2\]" 22 "io\[1\]" 23 "io\[0\]"]
|
||||
} else {
|
||||
puts "Error: Unknown chip for JEDEC file"
|
||||
exit
|
||||
}
|
||||
puts "Chip found to be $chip"
|
||||
|
||||
# Convert binary JEDEC file to hex for Verilog
|
||||
exec xxd -ps -c 1 __temp.bin ${chip}_reg.hex
|
||||
exec rm __temp.bin
|
||||
|
||||
# Read and synthesize original Verilog
|
||||
read_verilog $verilog_files
|
||||
hierarchy -auto-top
|
||||
flatten
|
||||
|
||||
tribuf
|
||||
synth
|
||||
#yosys proc
|
||||
#yosys memory
|
||||
#clean -purge
|
||||
flatten
|
||||
|
||||
splitnets -ports
|
||||
yosys rename -top __original
|
||||
select -module __original
|
||||
|
||||
# Process PCF file and rename ports
|
||||
set used [list]
|
||||
set pin_mapping [dict create 1 "clk" 2 "in\[0\]" 3 "in\[1\]" 4 "in\[2\]" 5 "in\[3\]" 6 "in\[4\]" 7 "in\[5\]" 8 "in\[6\]" 9 "in\[7\]" 11 "oe_n" 12 "io\[7\]" 13 "io\[6\]" 14 "io\[5\]" 15 "io\[4\]" 16 "io\[3\]" 17 "io\[2\]" 18 "io\[1\]" 19 "io\[0\]"]
|
||||
|
||||
set pcf_fp [open $pcf_file r]
|
||||
foreach line [split [read $pcf_fp] "\n"] {
|
||||
puts $line
|
||||
|
@ -45,10 +65,15 @@ select -clear
|
|||
design -stash __original
|
||||
|
||||
# Read and synthesize GAL model
|
||||
read_verilog wrapper.v GAL16V8_reg.v
|
||||
flatten
|
||||
read_verilog ${chip}_wrapper.v ${chip}_reg.v
|
||||
|
||||
tribuf
|
||||
synth
|
||||
#yosys proc
|
||||
#yosys memory
|
||||
#clean -purge
|
||||
flatten
|
||||
|
||||
splitnets -ports
|
||||
select -module __wrapper
|
||||
|
||||
|
@ -56,7 +81,7 @@ select -module __wrapper
|
|||
foreach pin_name [dict values $pin_mapping] {
|
||||
if {[lsearch -exact $used $pin_name] >= 0} {
|
||||
puts "$pin_name is used"
|
||||
} elseif {$pin_name == "oe_n"} {
|
||||
} elseif {$pin_name == "oe_n" && $chip == "GAL16V8"} {
|
||||
puts "$pin_name is not used"
|
||||
# Enable registered outputs if net unused
|
||||
connect -set __oe_n '0
|
||||
|
@ -74,4 +99,5 @@ design -copy-from __original -as __original A:top
|
|||
equiv_make __original __wrapper equiv
|
||||
tribuf -formal equiv
|
||||
equiv_induct equiv
|
||||
shell
|
||||
equiv_status -assert equiv
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
set_io clk 1
|
||||
set_io A 3
|
||||
set_io B 4
|
||||
set_io AND 13
|
||||
set_io NAND 14
|
||||
set_io REG_AND 15
|
||||
set_io AND 14
|
||||
set_io NAND 15
|
||||
set_io REG_AND 17
|
||||
set_io REG_NAND 16
|
||||
|
|
Loading…
Reference in a new issue