spiOverJtag: add real bridge (virtual jtag) for cyc1000 and build system based on edalize
This commit is contained in:
parent
c99f5aa4e6
commit
592cbd87b7
|
|
@ -199,8 +199,10 @@ add_definitions(-DFTDI_VERSION=${FTDI_VAL})
|
|||
|
||||
install(TARGETS openFPGALoader DESTINATION bin)
|
||||
file(GLOB BITS_FILES spiOverJtag/spiOverJtag_*.bit)
|
||||
file(GLOB RBF_FILES spiOverJtag/spiOverJtag_*.rbf)
|
||||
install(FILES
|
||||
test_sfl.svf
|
||||
${BITS_FILES}
|
||||
${RBF_FILES}
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/openFPGALoader
|
||||
)
|
||||
|
|
|
|||
13
README.md
13
README.md
|
|
@ -345,6 +345,9 @@ openFPGALoader -b boardname project_name.rbf
|
|||
with `boardname` = `de0`, `cyc1000`, `de0nano`, `de0nanoSoc` or `qmtechCycloneV`
|
||||
|
||||
#### SPI flash:
|
||||
|
||||
`RPD` and `RFP are supported
|
||||
|
||||
sof to rpd:
|
||||
```bash
|
||||
quartus_cpf -o auto_create_rpd=on -c -d EPCQ16A -s 10CL025YU256C8G project_name.svf project_name.jic
|
||||
|
|
@ -352,16 +355,10 @@ quartus_cpf -o auto_create_rpd=on -c -d EPCQ16A -s 10CL025YU256C8G project_name.
|
|||
file load:
|
||||
```bash
|
||||
openFPGALoader -b cyc1000 -r project_name_auto.rpd
|
||||
# or
|
||||
openFPGALoader -b cyc1000 -r project_name.rbf
|
||||
```
|
||||
|
||||
**Note about SPI flash:
|
||||
svf file used to write in flash is just a bridge between FT2232 interfaceB
|
||||
configured in SPI mode and sfl primitive used to access EPCQ SPI flash.**
|
||||
|
||||
**Note about FT2232 interfaceB:
|
||||
This interface is used for SPI communication only when the dedicated svf is
|
||||
loaded in RAM, rest of the time, user is free to use for what he want.**
|
||||
|
||||
<a id='xilinx'></a>
|
||||
### <span style="text-decoration:underline">Xilinx based boards</span>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
#*********************
|
||||
# Create Clock
|
||||
#*********************
|
||||
|
||||
set jtag_t_period 83
|
||||
create_clock -name {altera_reserved_tck} -period 83ns [get_ports {altera_reserved_tck}]
|
||||
set_clock_groups -asynchronous -group {altera_reserved_tck}
|
||||
#*********************
|
||||
# Create Generated Clock
|
||||
#*********************
|
||||
derive_pll_clocks
|
||||
#*********************
|
||||
# Set Clock Uncertainty
|
||||
#*********************
|
||||
derive_clock_uncertainty
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
module spiOverJtag ();
|
||||
wire tdi, tdo, tck;
|
||||
wire [8:0] ir_in;
|
||||
wire vs_cdr, vs_sdr, vs_uir;
|
||||
|
||||
sld_virtual_jtag #(.sld_auto_instance_index("YES"),
|
||||
.sld_instance_index(0), .sld_ir_width (9)
|
||||
) jtag_ctrl (
|
||||
.tdi(tdi), .tdo(tdo), .tck(tck), .ir_in(ir_in),
|
||||
.virtual_state_cdr(vs_cdr), .virtual_state_sdr(vs_sdr),
|
||||
.virtual_state_uir(vs_uir));
|
||||
|
||||
wire spi_csn, spi_si, spi_clk, spi_so;
|
||||
|
||||
altserial_flash_loader #(
|
||||
`ifdef cyclone10lp
|
||||
.INTENDED_DEVICE_FAMILY ("Cyclone 10 LP"),
|
||||
`elsif cycloneive
|
||||
.INTENDED_DEVICE_FAMILY ("Cyclone IV E"),
|
||||
`elsif cyclonev
|
||||
.INTENDED_DEVICE_FAMILY ("Cyclone V"),
|
||||
`endif
|
||||
.ENHANCED_MODE (1),
|
||||
.ENABLE_SHARED_ACCESS ("ON"),
|
||||
.ENABLE_QUAD_SPI_SUPPORT (0),
|
||||
.NCSO_WIDTH (1)
|
||||
) serial_flash_loader (
|
||||
.dclkin(spi_clk), .scein(spi_csn), .sdoin(spi_si), .data0out(spi_so),
|
||||
.data_in(), .data_oe(), .data_out(), .noe(1'b0),
|
||||
.asmi_access_granted (1'b1), .asmi_access_request ()
|
||||
);
|
||||
|
||||
/* vs_uir is used to send
|
||||
* command to the flash
|
||||
* and number of byte to generate
|
||||
*/
|
||||
reg [7:0] spi_cmd_s;
|
||||
reg sdr_d, cdr_d;
|
||||
always @(negedge tck) begin
|
||||
if (vs_uir) begin
|
||||
spi_cmd_s <= ir_in[7:0];
|
||||
end
|
||||
/* virtual state are updated on rising edge
|
||||
* and sampled at falling edge
|
||||
* => latch on negedge to use after on falling
|
||||
*/
|
||||
sdr_d <= vs_sdr;
|
||||
cdr_d <= vs_cdr;
|
||||
end
|
||||
|
||||
/* data in vs_sdr must be sampled on
|
||||
* rising edge but use state dealyed by
|
||||
* 1/2 clock cycle
|
||||
*/
|
||||
reg [7:0] test_s;
|
||||
reg tdi_d0_s;
|
||||
always @(posedge tck) begin
|
||||
if (cdr_d) begin
|
||||
test_s <= spi_cmd_s;
|
||||
end else if (sdr_d) begin
|
||||
test_s <= {tdi, test_s[7:1]};
|
||||
end
|
||||
tdi_d0_s <= tdi;
|
||||
end
|
||||
|
||||
reg spi_si_d;
|
||||
always @(negedge tck) begin
|
||||
if (vs_sdr | sdr_d)
|
||||
spi_si_d <= test_s[0];
|
||||
end
|
||||
|
||||
assign spi_csn = !sdr_d;
|
||||
assign spi_si = (sdr_d) ? spi_si_d : 1'b0;
|
||||
assign spi_clk = sdr_d ? tck : 1'b0;
|
||||
assign tdo = sdr_d ? spi_so : tdi_d0_s;
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
#!/usr/bin/env python3
|
||||
from edalize import get_edatool
|
||||
import os
|
||||
|
||||
if len(os.sys.argv) != 2:
|
||||
print("missing board param")
|
||||
os.sys.exit()
|
||||
part = os.sys.argv[1]
|
||||
|
||||
build_dir="tmp_" + part
|
||||
if not os.path.isdir(build_dir):
|
||||
try:
|
||||
os.mkdir(build_dir)
|
||||
except OSError:
|
||||
print ("Creation of the directory %s failed" % build_dir)
|
||||
else:
|
||||
print ("Successfully created the directory %s " % build_dir)
|
||||
|
||||
currDir = os.path.abspath(os.path.curdir) + '/'
|
||||
|
||||
subpart = part[0:4].lower()
|
||||
if subpart == '10cl':
|
||||
family = "Cyclone 10 LP"
|
||||
tool = "quartus"
|
||||
elif subpart == 'ep4c':
|
||||
family = "Cyclone IV E"
|
||||
tool = "quartus"
|
||||
elif subpart[0:2] == '5c':
|
||||
family = "Cyclone V"
|
||||
tool = "quartus"
|
||||
elif subpart == "xc7a":
|
||||
family = "Artix"
|
||||
tool = "vivado"
|
||||
elif subpart == "xc7s":
|
||||
family = "Spartan 7"
|
||||
tool = "vivado"
|
||||
elif subpart == "xc6s":
|
||||
family = "Spartan 6"
|
||||
tool = "ise"
|
||||
else:
|
||||
print("Error: unknown device")
|
||||
os.sys.exit()
|
||||
|
||||
files = []
|
||||
|
||||
if tool in ["ise", "vivado"]:
|
||||
pkg_name = {
|
||||
"xc7a35tcpg236" : "xc7a_cpg236",
|
||||
"xc7a35tcsg324g236": "xc7a_csg324",
|
||||
"xc7a35tftg256g236": "xc7a_ftg256",
|
||||
"xc7a50tcpg236g236": "xc7a_cpg236",
|
||||
"xc7a75tfgg484g236": "xc7a_fgg484",
|
||||
"xc7a100tfgg484" : "xc7a_fgg484",
|
||||
"xc7a200tsbg484" : "xc7a_sbg484",
|
||||
"xc7a200tfbg484" : "xc7a_fbg484",
|
||||
"xc7s50csga324" : "xc7s_csga324"
|
||||
}[part]
|
||||
if tool == "ise":
|
||||
cst_type = "UCF"
|
||||
else:
|
||||
cst_type = "xdc"
|
||||
cst_file = currDir + "constr_" + pkg_name + "." + cst_type
|
||||
files.append({'name': currDir + 'xilinx_spiOverJtag.v',
|
||||
'file_type': 'verilogSource'})
|
||||
files.append({'name': cst_file, 'file_type': cst_type})
|
||||
tool_options = {'part': part+ '-1'}
|
||||
else:
|
||||
full_part = {
|
||||
"10cl025256": "10CL025YU256C8G",
|
||||
"ep4ce2217" : "EP4CE22F17C6",
|
||||
"5ce223" : "5CEFA2F23I7"}[part]
|
||||
files.append({'name': currDir + 'altera_spiOverJtag.v',
|
||||
'file_type': 'verilogSource'})
|
||||
files.append({'name': currDir + 'test_jtag.sdc',
|
||||
'file_type': 'SDC'})
|
||||
tool_options = {'device': full_part, 'family':family}
|
||||
|
||||
parameters = {}
|
||||
parameters[family.lower().replace(' ', '')]= {
|
||||
'datatype': 'int',
|
||||
'paramtype': 'vlogdefine',
|
||||
'description': 'fpga family',
|
||||
'default': 1}
|
||||
|
||||
edam = {'name' : "spiOverJtag",
|
||||
'files': files,
|
||||
'tool_options': {tool: tool_options},
|
||||
'parameters': parameters,
|
||||
'toplevel' : 'spiOverJtag',
|
||||
}
|
||||
|
||||
backend = get_edatool(tool)(edam=edam, work_root=build_dir)
|
||||
backend.configure()
|
||||
backend.build()
|
||||
Binary file not shown.
Loading…
Reference in New Issue