OpenCores
URL https://opencores.org/ocsvn/openarty/openarty/trunk

Subversion Repositories openarty

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openarty/trunk/rtl
    from Rev 12 to Rev 13
    Reverse comparison

Rev 12 → Rev 13

/xioddr.v
5,7 → 5,11
// Project: OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose: For the DDR3 SDRAM, this handles the Xilinx specific portions
// of the IO necessary to make this happen for one pin only.
// of the IO necessary to make this happen for one pin only. (In
// the end, this never worked for the DDR3 SDRAM ...) In the case of the
// QSPI flash, this module helps to reduce the logic delays on the "high
// speed" flash data wires (it's not really used in any DDR mode in that
// case ...).
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
36,16 → 40,19
////////////////////////////////////////////////////////////////////////////////
//
//
module xioddr(i_clk, i_oe, i_v, o_v, io_w);
module xioddr(i_clk, i_oe, i_v, o_v, io_pin);
input i_clk, i_oe;
input [1:0] i_v;
output [1:0] o_v;
inout io_w;
inout io_pin;
 
wire w_internal;
reg last;
always @(posedge i_clk)
last <= i_v[1];
 
ODDR #(
.DDR_CLK_EDGE("OPPOSITE_EDGE"),
.DDR_CLK_EDGE("SAME_EDGE"),
.INIT(1'b0),
.SRTYPE("SYNC")
) ODDRi(
52,13 → 59,13
.Q(w_internal),
.C(i_clk),
.CE(1'b1),
.D1(i_v[0]),
.D2(i_v[1]),
.D1(last), // Negative clock edge
.D2(i_v[0]), // Positive clock edge
.R(1'b0),
.S(1'b0));
 
IDDR #(
.DDR_CLK_EDGE("OPPOSITE_EDGE"),
.DDR_CLK_EDGE("SAME_EDGE_PIPELINED"),
.INIT_Q1(1'b0),
.INIT_Q2(1'b0),
.SRTYPE("SYNC")
67,10 → 74,10
.Q2(o_v[1]),
.C(i_clk),
.CE(1'b1),
.D(io_w),
.D(io_pin),
.R(1'b0),
.S(1'b0));
 
assign io_w = (i_oe) ? w_internal:1'bz;
assign io_pin = (i_oe) ? w_internal:1'bz;
 
endmodule
/eqspiflash.v
724,7 → 724,8
accepted <= (~i_spi_busy)&&(i_grant)&&(o_spi_wr)&&(~accepted);
 
reg [3:0] rd_state;
reg r_leave_xip, r_xip, r_quad, r_requested, ack_valid;
reg r_leave_xip, r_xip, r_quad, r_requested;
reg [3:0] invalid_ack_pipe;
initial rd_state = `RD_IDLE;
initial o_data_ack = 1'b0;
initial o_bus_ack = 1'b0;
736,9 → 737,9
o_spi_recycle <= 1'b0;
if (i_spi_valid)
o_data <= i_spi_data;
invalid_ack_pipe <= { invalid_ack_pipe[2:0], accepted };
case(rd_state)
`RD_IDLE: begin
ack_valid <= 1'b0;
r_requested <= 1'b0;
o_qspi_req <= 1'b0;
o_spi_word <= { ((i_quad)? 8'h6B: 8'h0b), i_addr, 2'b00 };
757,7 → 758,6
`RD_IDLE_GET_PORT: begin
o_spi_wr <= 1'b1; // Write the address
o_qspi_req <= 1'b1;
ack_valid <= 1'b0;
if (accepted)
rd_state <= `RD_SLOW_DUMMY;
end
768,7 → 768,6
o_spi_spd <= 1'b0;
o_spi_word[31:24] <= (r_xip) ? 8'h00 : 8'hff;
o_spi_len <= 2'b00; // 8 clocks = 8-bits
ack_valid <= 1'b0;
if (accepted)
rd_state <= (r_quad)?`RD_QUAD_READ_DATA
: `RD_SLOW_READ_DATA;
779,12 → 778,10
o_spi_spd <= 1'b0;
o_spi_len <= 2'b11;
o_spi_wr <= (~r_requested)||(i_piperd);
// if (accepted)
// o_spi_wr <= (i_piperd);
o_data_ack <= (ack_valid)&&(i_spi_valid);
invalid_ack_pipe[0] <= (!r_requested);
o_data_ack <= (!invalid_ack_pipe[3])&&(i_spi_valid)&&(r_requested);
o_bus_ack <= (r_requested)&&(accepted)&&(i_piperd);
r_requested <= (r_requested)||(accepted);
ack_valid <= (accepted)?(r_requested):ack_valid;
if ((i_spi_valid)&&(~o_spi_wr))
rd_state <= `RD_GO_TO_IDLE;
end
794,9 → 791,9
o_spi_spd <= 1'b1;
o_spi_len <= 2'b11;
o_spi_recycle <= (r_leave_xip)? 1'b1: 1'b0;
invalid_ack_pipe[0] <= (!r_requested);
r_requested <= (r_requested)||(accepted);
ack_valid <= (r_requested);
o_data_ack <= (ack_valid)&&(i_spi_valid)&&(~r_leave_xip);
o_data_ack <= (!invalid_ack_pipe[3])&&(i_spi_valid)&&(r_requested)&&(~r_leave_xip);
o_bus_ack <= (r_requested)&&(accepted)&&(i_piperd)&&(~r_leave_xip);
o_spi_wr <= (~r_requested)||(i_piperd);
// if (accepted)
844,8 → 841,8
o_bus_ack <= i_readreq;
end end
`RD_GO_TO_IDLE: begin
r_requested <= 1'b0;
ack_valid <= 1'b0;
if ((!invalid_ack_pipe[3])&&(i_spi_valid)&&(~r_leave_xip))
o_data_ack <= 1'b1;
o_spi_wr <= 1'b0;
o_qspi_req <= 1'b0;
if ((i_spi_stopped)&&(~i_grant))
853,7 → 850,8
end
`RD_GO_TO_XIP: begin
r_requested <= 1'b0;
ack_valid <= 1'b0;
if ((i_spi_valid)&&(!invalid_ack_pipe[3]))
o_data_ack <= 1'b1;
o_qspi_req <= 1'b1;
o_spi_wr <= 1'b0;
if (i_spi_stopped)
943,7 → 941,6
chk_wip <= 1'b0;
o_bus_ack <= 1'b0;
o_data_ack <= 1'b0;
cyc <= (cyc)&&(~i_endpipe);
case(wr_state)
`WR_IDLE: begin
valid_status <= 1'b0;
1010,6 → 1007,7
o_spi_spd <= i_quad;
o_spi_hold <= 1'b1;
o_spi_word <= i_data;
cyc <= (cyc)&&(~i_endpipe);
if (~cyc)
wr_state <= `WR_WAIT_ON_STOP;
else if (i_pipewr)
1160,6 → 1158,7
 
reg [2:0] ctstate;
reg accepted;
reg [3:0] invalid_ack_pipe;
 
 
initial accepted = 1'b0;
1278,6 → 1277,7
o_spi_wr <= 1'b1;
o_bus_ack <= 1'b0;
o_data_ack <= 1'b0;
invalid_ack_pipe <= { invalid_ack_pipe[2:0], accepted };
if (i_spi_valid)
o_data <= i_spi_data;
case(ctstate)
1322,9 → 1322,8
`CT_READ_DATA: begin
o_spi_wr <= 1'b0; // No more words to go, just to wait
o_spi_req <= 1'b1;
if (i_spi_valid)
first_valid <= 1'b1;
if ((i_spi_valid)&&(first_valid)) // for a value to read
invalid_ack_pipe[0] <= 1'b0;
if ((i_spi_valid)&&(!invalid_ack_pipe[3])) // for a value to read
begin
o_data_ack <= 1'b1;
o_data <= i_spi_data;
1442,8 → 1441,9
reg nxt_data_ack, nxt_data_spi;
reg [31:0] nxt_data;
 
reg set_val, chk_wip, first_valid, valid_status;
reg set_val, chk_wip, first_valid;
reg [2:0] set_addr;
reg [3:0] invalid_ack_pipe;
 
always @(posedge i_clk)
begin // Depends upon state[4], otp_rd, otp_wr, otp_pipe, id_req, accepted, last_addr
1454,6 → 1454,7
nxt_data_spi <= 1'b0;
chk_wip <= 1'b0;
set_val <= 1'b0;
invalid_ack_pipe <= { invalid_ack_pipe[2:0], accepted };
if ((id_loaded)&&(id_read_request))
begin
nxt_data_ack <= 1'b1;
1527,9 → 1528,8
o_spi_wr <= (~last_addr); // Still transmitting
o_spi_dir <= 1'b1; // Read from SPI
o_qspi_req <= 1'b1;
if (i_spi_valid) // two clocks after accepted
first_valid <= 1'b1;
if((i_spi_valid)&&(first_valid))
invalid_ack_pipe[0] <= 1'b0;
if((i_spi_valid)&&(!invalid_ack_pipe[3]))
begin
set_val <= 1'b1;
set_addr <= lcl_id_addr[2:0];
1567,9 → 1567,8
id_state <= `ID_OTP_GET_DATA;
end
`ID_OTP_GET_DATA: begin
if (i_spi_valid)
first_valid <= 1'b1;
if ((i_spi_valid)&&(first_valid))
invalid_ack_pipe[0] <= 1'b0;
if ((i_spi_valid)&&(!invalid_ack_pipe[3]))
begin
id_state <= `ID_FINAL_STOP;
nxt_data_ack <= 1'b1;
1609,7 → 1608,6
o_spi_dir <= 1'b1; // Read
o_spi_len <= 2'b00; // 8 bits
// o_spi_word <= dont care
valid_status <= 1'b0;
if (accepted)
id_state <= `ID_READ_STATUS;
end
1619,9 → 1617,8
o_spi_dir <= 1'b1; // Read
o_spi_len <= 2'b00; // 8 bits
// o_spi_word <= dont care
if (i_spi_valid)
valid_status <= 1'b1;
if ((i_spi_valid)&&(valid_status))
invalid_ack_pipe[0] <= 1'b0;
if ((i_spi_valid)&&(~invalid_ack_pipe[3]))
chk_wip <= 1'b1;
if ((chk_wip)&&(~i_spi_data[0]))
begin
/fastmaster.v
62,10 → 62,20
`define RTC_ACCESS
`define OLEDRGB_ACCESS
//
`define FLASH_SCOPE // Position zero
`ifdef FLASH_ACCESS
`define FLASH_SCOPE // Position zero
`else
`ifdef ZIPCPU
// `define CPU_SCOPE // Position zero
`endif
`endif
// `define GPS_SCOPE // Position one
`ifdef ICAPE_ACCESS
`define CFG_SCOPE // Position one
`endif
`ifdef SDRAM_ACCESS
// `define SDRAM_SCOPE // Position two
`endif
// `define ENET_SCOPE
//
//
377,16 → 387,17
mem_ack, flash_ack, ram_ack;
reg many_ack, slow_many_ack;
reg slow_ack, scop_ack;
wire [4:0] ack_list;
assign ack_list = { ram_ack, flash_ack, mem_ack, netb_ack, cfg_ack };
wire [5:0] ack_list;
assign ack_list = { ram_ack, flash_ack, mem_ack, netb_ack, netp_ack, slow_ack };
initial many_ack = 1'b0;
always @(posedge i_clk)
many_ack <= ((ack_list != 5'h10)
&&(ack_list != 5'h8)
&&(ack_list != 5'h4)
&&(ack_list != 5'h2)
&&(ack_list != 5'h1)
&&(ack_list != 5'h0));
many_ack <= ((ack_list != 6'h20)
&&(ack_list != 6'h10)
&&(ack_list != 6'h8)
&&(ack_list != 6'h4)
&&(ack_list != 6'h2)
&&(ack_list != 6'h1)
&&(ack_list != 6'h0));
/*
assign many_ack = ( { 2'h0, ram_ack}
+{2'h0, flash_ack }
396,7 → 407,7
*/
 
wire [7:0] slow_ack_list;
assign slow_ack_list = { mio_ack, gps_ack, netp_ack,
assign slow_ack_list = { cfg_ack, mio_ack, gps_ack,
sdcard_ack, rtc_ack, scop_ack, oled_ack, io_ack };
initial slow_many_ack = 1'b0;
always @(posedge i_clk)
411,12 → 422,9
&&(slow_ack_list != 8'h00));
 
always @(posedge i_clk)
wb_ack <= (wb_cyc)&&(|{ ram_ack, flash_ack, mem_ack,
netb_ack, cfg_ack, slow_ack });
wb_ack <= (wb_cyc)&&(|ack_list);
always @(posedge i_clk)
slow_ack <= (wb_cyc)&&(|{oled_ack, mio_ack, gps_ack,
netp_ack, sdcard_ack, rtc_ack, scop_ack,
oled_ack, io_ack});
slow_ack <= (wb_cyc)&&(|slow_ack_list);
 
//
// Peripheral data lines
434,20 → 442,18
else if ((mem_ack)||(netb_ack))
wb_idata <= (mem_ack)?mem_data:netb_data;
else
wb_idata <= slow_data;
wb_idata <= (netp_ack)?netp_data: slow_data;
 
// 7 control lines, 8x32 data lines
always @(posedge i_clk)
if ((cfg_ack)||(mio_ack))
slow_data <= (cfg_ack) ? cfg_data : mio_data;
else if ((gps_ack)||(netp_ack))
slow_data <= (gps_ack) ? gps_data : netp_data;
else if ((sdcard_ack)||(rtc_ack))
slow_data <= (sdcard_ack)?sdcard_data : rtc_data;
else if ((scop_ack)|(oled_ack))
slow_data <= (scop_ack)?scop_data:oled_data;
else
slow_data <= io_data;
slow_data <= (gps_ack) ? gps_data : io_data;
 
//
// Peripheral stall lines
467,7 → 473,7
||((sdcard_sel)&&(sdcard_stall))// Never stalls
||((netp_sel)&&(netp_stall))
||((gps_sel)&&(gps_stall)) //(maybe? never stalls?)
||((oled_sel)&&(oled_stall))
||((oled_sel)&&(oled_stall)) // Never stalls
||((mio_sel)&&(mio_stall))
||((cfg_sel)&&(cfg_stall))
||((netb_sel)&&(netb_stall)) // Never stalls
847,9 → 853,10
// MULTIBOOT/ICAPE2 CONFIGURATION ACCESS
//
`ifdef ICAPE_ACCESS
wire [31:0] cfg_debug;
wbicapetwo fpga_cfg(i_clk, wb_cyc,(cfg_sel)&&(wb_stb), wb_we,
wb_addr[4:0], wb_data,
cfg_ack, cfg_stall, cfg_data);
cfg_ack, cfg_stall, cfg_data, cfg_debug);
`else
reg r_cfg_ack;
always @(posedge i_clk)
1018,7 → 1025,33
wb_we, wb_addr[0], wb_data,
scop_gps_ack, scop_gps_stall, scop_gps_data,
scop_gps_interrupt);
 
assign scop_b_ack = scop_gps_ack;
assign scop_b_stall = scop_gps_stall;
assign scop_b_data = scop_gps_data;
assign scop_b_interrupt = scop_gps_interrupt;
`else
`ifdef CFG_SCOPE
wire [31:0] scop_cfg_data;
wire scop_cfg_ack, scop_cfg_stall, scop_cfg_interrupt;
wire [31:0] cfg_debug_2;
assign cfg_debug_2 = {
wb_ack, cfg_debug[30:17], slow_ack,
slow_data[7:0], wb_data[7:0]
};
wbscope #(5'd8,32,1) cfgscope(i_clk, 1'b1, (cfg_sel)&&(wb_stb),
cfg_debug_2,
// Wishbone interface
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b01)),
wb_we, wb_addr[0], wb_data,
scop_cfg_ack, scop_cfg_stall, scop_cfg_data,
scop_cfg_interrupt);
 
assign scop_b_data = scop_cfg_data;
assign scop_b_stall = scop_cfg_stall;
assign scop_b_ack = scop_cfg_ack;
assign scop_b_interrupt = scop_cfg_interrupt;
`else
assign scop_b_data = 32'h00;
assign scop_b_stall = 1'b0;
assign scop_b_interrupt = 1'b0;
1028,6 → 1061,7
r_scop_b_ack <= (wb_stb)&&(scop_sel)&&(wb_addr[2:1] == 2'b01);
assign scop_b_ack = r_scop_b_ack;
`endif
`endif
 
//
// SCOPE C
1088,10 → 1122,16
assign scop_d_ack = r_scop_d_ack;
//`endif
 
assign scop_int = scop_a_interrupt
|| scop_b_interrupt
|| scop_c_interrupt
|| scop_d_interrupt;
reg all_scope_interrupts;
always @(posedge i_clk)
all_scope_interrupts <= (scop_a_interrupt)
|| (scop_b_interrupt)
|| (scop_c_interrupt)
|| (scop_d_interrupt);
assign scop_int = all_scope_interrupts;
 
// Scopes don't stall, so this line is more formality than anything
// else.
assign scop_stall = ((wb_addr[2:1]==2'b0)?scop_a_stall
: ((wb_addr[2:1]==2'b01)?scop_b_stall
: ((wb_addr[2:1]==2'b11)?scop_c_stall
/xoddr.v
0,0 → 1,66
////////////////////////////////////////////////////////////////////////////////
//
// Filename: xoddr.v
//
// Project: OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose: For the DDR3 SDRAM, this handles the Xilinx specific portions
// of the output necessary to make this happen for one pin only.
// For the QSPI, this helps to make certain that as much of the logic
// delay as possible has been removed from the path--to get the full
// 100MHz speed.
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 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 MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. (It's in the $(ROOT)/doc directory, run make with no
// target there if the PDF file isn't present.) If not, see
// <http://www.gnu.org/licenses/> for a copy.
//
// License: GPL, v3, as defined and found on www.gnu.org,
// http://www.gnu.org/licenses/gpl.html
//
//
////////////////////////////////////////////////////////////////////////////////
//
//
module xoddr(i_clk, i_v, o_pin);
input i_clk;
input [1:0] i_v;
output o_pin;
 
wire w_internal;
reg last;
 
always @(posedge i_clk)
last <= i_v[1];
 
ODDR #(
.DDR_CLK_EDGE("SAME_EDGE"),
.INIT(1'b0),
.SRTYPE("SYNC")
) ODDRi(
.Q(o_pin),
.C(i_clk),
.CE(1'b1),
.D1(last), // Negative clock edge (goes first)
.D2(i_v[0]), // Positive clock edge
.R(1'b0),
.S(1'b0));
 
endmodule
/fasttop.v
214,7 → 214,7
//
//
//////
wire w_qspi_sck;
wire w_qspi_sck, w_qspi_cs_n;
wire [1:0] qspi_bmod;
wire [3:0] qspi_dat;
wire [3:0] i_qspi_dat;
241,7 → 241,7
// Board level PMod I/O
i_aux_rx, o_aux_tx, o_aux_cts, i_gps_rx, o_gps_tx,
// Quad SPI flash
o_qspi_cs_n, w_qspi_sck, qspi_dat, io_qspi_dat, qspi_bmod,
w_qspi_cs_n, w_qspi_sck, qspi_dat, i_qspi_dat, qspi_bmod,
// DDR3 SDRAM
o_ddr_reset_n, o_ddr_cke,
w_ddr_cs_n, w_ddr_ras_n, w_ddr_cas_n, w_ddr_we_n,
278,7 → 278,7
// ?? Dual mode out (not yet)
//
//
`define QSPI_OUT_VERSION_ONE
// `define QSPI_OUT_VERSION_ONE
`ifdef QSPI_OUT_VERSION_ONE
assign io_qspi_dat = (~qspi_bmod[1])?({2'b11,1'bz,qspi_dat[0]})
:((qspi_bmod[0])?(4'bzzzz):(qspi_dat[3:0]));
285,104 → 285,29
assign i_qspi_dat = io_qspi_dat;
assign o_qspi_sck = w_qspi_sck;
`else
wire [3:0] i_qspi_ignore;
wire [3:0] i_qspi_pedge, i_qspi_nedge;
 
xoddr xqspi_sck( i_clk, { w_qspi_sck, w_qspi_sck }, o_qspi_sck);
xoddr xqspi_csn( i_clk, { w_qspi_cs_n, w_qspi_cs_n },o_qspi_cs_n);
//
xioddr xqspi_d0( i_clk, (~qspi_bmod[0])||(~qspi_bmod[1]),
xioddr xqspi_d0( i_clk, (qspi_bmod != 2'b11),
{ qspi_dat[0], qspi_dat[0] },
{ i_qspi_ignore[0], i_qspi_dat[0] }, io_qspi_dat[0]);
{ i_qspi_pedge[0], i_qspi_nedge[0] }, io_qspi_dat[0]);
xioddr xqspi_d1( i_clk, (qspi_bmod==2'b10),
{ qspi_dat[1], qspi_dat[1] },
{ i_qspi_ignore[1], i_qspi_dat[1] }, io_qspi_dat[1]);
{ i_qspi_pedge[1], i_qspi_nedge[1] }, io_qspi_dat[1]);
xioddr xqspi_d2( i_clk, (qspi_bmod!=2'b11),
(qspi_bmod[1])?{ qspi_dat[2], qspi_dat[2] }:2'b11,
{ i_qspi_ignore[2], i_qspi_dat[2] }, io_qspi_dat[2]);
{ i_qspi_pedge[2], i_qspi_nedge[2] }, io_qspi_dat[2]);
xioddr xqspi_d3( i_clk, (qspi_bmod!=2'b11),
(qspi_bmod[1])?{ qspi_dat[3], qspi_dat[3] }:2'b11,
{ i_qspi_ignore[3], i_qspi_dat[3] }, io_qspi_dat[3]);
{ i_qspi_pedge[3], i_qspi_nedge[3] }, io_qspi_dat[3]);
 
assign i_qspi_dat = i_qspi_pedge;
`endif
 
//
// Proposed QSPI mode select, to allow dual I/O mode
// 000 Normal SPI mode
// 001 Dual mode input
// 010 Dual mode, output
// 101 Quad I/O mode input
// 110 Quad I/O mode output
//
//
// assign io_qspi_dat[3:2] = (~qspi_bmod[2]) ? 2'b11
// : (qspi_bmod[0])?2'bzz : qspi_dat[3:2];
// assign io_qspi_dat[1] = (~qspi_bmod[1])?qspi_dat[1]:1'bz;
// assign io_qspi_dat[0] = (qspi_bmod[0])?1'bz : qspi_dat[0];
 
//
//
// The following primitive is necessary on other boards in order to
// gain access to the o_qspi_sck pin. On the Arty, however, there is
// a clock PIN, so we don't need this primitive.
//
//
/*
wire [3:0] su_nc; // Startup primitive, no connect
STARTUPE2 #(
// Leave PROG_USR false to avoid activating the program
// event security feature. Notes state that such a feature
// requires encrypted bitstreams.
.PROG_USR("FALSE"),
// Sets the configuration clock frequency (in ns) for
// simulation.
.SIM_CCLK_FREQ(0.0)
) STARTUPE2_inst (
// CFGCLK, 1'b output: Configuration main clock output -- no connect
.CFGCLK(su_nc[0]),
// CFGMCLK, 1'b output: Configuration internal oscillator clock output
.CFGMCLK(su_nc[1]),
// EOS, 1'b output: Active high output indicating the End Of Startup.
.EOS(su_nc[2]),
// PREQ, 1'b output: PROGRAM request to fabric output
// Only enabled if PROG_USR is set. This lets the fabric know
// that a request has been made (either JTAG or pin pulled low)
// to program the device
.PREQ(su_nc[3]),
// CLK, 1'b input: User start-up clock input
.CLK(1'b0),
// GSR, 1'b input: Global Set/Reset input
.GSR(1'b0),
// GTS, 1'b input: Global 3-state input
.GTS(1'b0),
// KEYCLEARB, 1'b input: Clear AES Decrypter Key input from BBRAM
.KEYCLEARB(1'b0),
// PACK, 1-bit input: PROGRAM acknowledge input
// This pin is only enabled if PROG_USR is set. This allows the
// FPGA to acknowledge a request for reprogram to allow the FPGA
// to get itself into a reprogrammable state first.
.PACK(1'b0),
// USRCLKO, 1-bit input: User CCLK input -- This is why I am using this
// module at all.
.USRCCLKO(qspi_sck),
// USRCCLKTS, 1'b input: User CCLK 3-state enable input
// An active high here places the clock into a high impedence
// state. Since we wish to use the clock as an active output
// always, we drive this pin low.
.USRCCLKTS(1'b0),
// USRDONEO, 1'b input: User DONE pin output control
// Set this to "high" to make sure that the DONE LED pin is
// high.
.USRDONEO(1'b1),
// USRDONETS, 1'b input: User DONE 3-state enable output
// This enables the FPGA DONE pin to be active. Setting this
// active high sets the DONE pin to high impedence, setting it
// low allows the output of this pin to be as stated above.
.USRDONETS(1'b1)
);
*/
 
 
 
//
//
// Wires for setting up the SD Card Controller
//
//
/builddate.v
38,4 → 38,4
////////////////////////////////////////////////////////////////////////////////
//
//
`define DATESTAMP 32'h20160810
`define DATESTAMP 32'h20160811
/wbscope.v
101,6 → 101,17
// being stopped. It is not maskable here.
output wire o_interrupt;
 
// For timing's sake, let's remove ourselves from the bus a touch
reg r_wb_stb, r_wb_addr, r_wb_we;
reg [31:0] r_wb_data;
always @(posedge i_clk)
begin
r_wb_stb <= i_wb_stb;
r_wb_we <= i_wb_we;
r_wb_addr<= i_wb_addr;
r_wb_data<= i_wb_data;
end
 
reg [(LGMEM-1):0] raddr;
reg [(BUSW-1):0] mem[0:((1<<LGMEM)-1)];
 
111,13 → 122,13
wire [19:0] bw_holdoff;
initial br_config = ((1<<(LGMEM-1))-4);
always @(posedge i_wb_clk)
if ((i_wb_stb)&&(~i_wb_addr))
if ((r_wb_stb)&&(~r_wb_addr))
begin
if (i_wb_we)
br_config <= { i_wb_data[31],
(i_wb_data[27]),
i_wb_data[26],
i_wb_data[19:0] };
if (r_wb_we)
br_config <= { r_wb_data[31],
(r_wb_data[27]),
r_wb_data[26],
r_wb_data[19:0] };
end else if (bw_reset_complete)
br_config[22] <= 1'b1;
assign bw_reset_request = (~br_config[22]);
273,21 → 284,26
end endgenerate
 
// Reads use the bus clock
reg br_wb_ack, r_wb_ack; // takes one clock to read
wire bw_cyc_stb, bus_read_fifo;
assign bw_cyc_stb = (i_wb_stb);
assign bus_read_fifo = (i_wb_stb)&&(i_wb_addr)&&(~i_wb_we);
reg br_wb_ack, r_wb_ack, s_wb_ack; // takes two clock to read
reg s_wb_addr, q_wb_addr;
reg bw_cyc_stb, bus_read_fifo, bus_write_fifo;
always @(posedge i_clk)
bw_cyc_stb = (r_wb_stb);
always @(posedge i_clk)
bus_read_fifo <= (r_wb_stb)&&(r_wb_addr)&&(~r_wb_we);
always @(posedge i_clk)
bus_write_fifo <= (r_wb_stb)&&(r_wb_addr)&&(r_wb_we);
initial br_wb_ack = 1'b0;
always @(posedge i_wb_clk)
begin // CE depends upon 5 inputs, output on 7 (ignoring add&carries)
if ((bw_reset_request)
||((bw_cyc_stb)&&(i_wb_addr)&&(i_wb_we)))
if ((bw_reset_request)||(bus_write_fifo))
raddr <= 0;
else if ((bus_read_fifo)&&(bw_stopped))
raddr <= raddr + {{(LGMEM-1){1'b0}},1'b1}; // Data read, when stopped
 
r_wb_ack <= i_wb_stb;
br_wb_ack <= r_wb_ack;
r_wb_ack <= r_wb_stb;
s_wb_ack <= r_wb_ack;
br_wb_ack <= s_wb_ack;
end
 
reg [(LGMEM-1):0] nxt_addr;
303,14 → 319,15
always @(posedge i_wb_clk)
nxt_mem <= mem[nxt_addr];
 
reg r_wb_addr;
always @(posedge i_clk)
r_wb_addr <= i_wb_addr;
s_wb_addr <= r_wb_addr;
always @(posedge i_clk)
q_wb_addr <= s_wb_addr;
 
wire [4:0] bw_lgmem;
assign bw_lgmem = LGMEM;
always @(posedge i_wb_clk)
if (~r_wb_addr) // Control register read
if (~q_wb_addr) // Control register read
o_wb_data <= { bw_reset_request,
bw_stopped,
bw_triggered,
326,7 → 343,7
o_wb_data <= nxt_mem; // mem[raddr+waddr];
 
assign o_wb_stall = 1'b0;
assign o_wb_ack = (br_wb_ack);
assign o_wb_ack = (s_wb_ack);
 
reg br_level_interrupt;
initial br_level_interrupt = 1'b0;
/wbicapetwo.v
95,7 → 95,7
`define MBOOT_DESYNC 5'h11
module wbicapetwo(i_clk,
i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data,
o_wb_ack, o_wb_stall, o_wb_data);
o_wb_ack, o_wb_stall, o_wb_data, o_dbg);
input i_clk;
// Wishbone inputs
input i_wb_cyc, i_wb_stb, i_wb_we;
104,6 → 104,8
// Wishbone outputs
output reg o_wb_ack, o_wb_stall;
output reg [31:0] o_wb_data;
// Debugging output
output wire [31:0] o_dbg;
// ICAPE2 interface signals
// These are kept internal to this block ...
 
111,7 → 113,38
reg [31:0] r_data;
reg [4:0] r_addr;
 
reg slow_clk;
`ifdef DIVIDE_BY_FOUR
reg [1:0] slow_clk_counter;
reg clk_stb, clk_stall;
wire slow_clk;
always @(posedge i_clk)
begin
slow_clk <= slow_clk + 2'b01;
// We'll move on the positive edge of the clock, so therefore
// clk_stb must be true one clock before that, so we test for
// it one clock before that.
clk_stb <= (slow_clk_counter == 2'b10);
// CLK_STALL is set to true two clocks before any cycle that
// will, by necessity, stall.
clk_stall <= (slow_clk_counter != 2'b01);
end
 
assign slow_clk = slow_clk_counter[1];
`else
reg slow_clk, clk_stb, clk_stall;
always @(posedge i_clk)
begin
slow_clk <= (slow_clk + 1'b1);
// We'll move on the positive edge of the clock, so therefore
// clk_stb must be true one clock before that, so we test for
// it one clock before that.
clk_stb <= (slow_clk == 1'b1);
// CLK_STALL is set to true two clocks before any cycle that
// will, by necessity, stall.
clk_stall <= (slow_clk != 1'b0); //True all but one clock
end
`endif
 
reg [31:0] cfg_in;
reg cfg_cs_n, cfg_rdwrn;
wire [31:0] cfg_out;
120,13 → 153,19
initial cfg_cs_n = 1'b1;
always @(posedge i_clk)
begin
// In general, o_wb_ack is always zero. The exceptions to this
// will be handled individually below.
o_wb_ack <= 1'b0;
// We can simplify our logic a touch by always setting
// o_wb_data. It will only be examined if o_wb_ack
// is also true, so this is okay.
o_wb_data <= cfg_out;
 
// Turn any request "off", so that it will not be ack'd, if
// the wb_cyc line is ever lowered.
wb_req <= wb_req & i_wb_cyc;
slow_clk <= slow_clk ^ 1'b1;
o_wb_stall <= (state != `MBOOT_IDLE)&&(slow_clk);
if (~slow_clk)
o_wb_stall <= (state != `MBOOT_IDLE)||(clk_stall);
if (clk_stb)
begin
state <= state + 5'h01;
case(state)
142,7 → 181,7
r_addr <= i_wb_addr;
r_data <= i_wb_data;
r_we <= i_wb_we;
if(i_wb_stb)
if(i_wb_stb) // &&(!o_wb_stall)
begin
state <= `MBOOT_START;
wb_req <= 1'b1;
149,21 → 188,40
//
o_wb_ack <= 1'b0;
end end
`MBOOT_START: cfg_in <= 32'hffffffff; // NOOP
`MBOOT_START: begin
cfg_in <= 32'hffffffff; // NOOP
cfg_cs_n <= 1'b1;
end
5'h02: begin
cfg_cs_n <= 1'b0; // Activate interface
cfg_rdwrn <= 1'b0;
cfg_in <= 32'h20000000; // NOOP
end
5'h03: cfg_in <= 32'haa995566; // Sync word
5'h04: cfg_in <= 32'h20000000; // NOOP
5'h03: begin
cfg_in <= 32'haa995566; // Sync word
cfg_cs_n <= 1'b0;
end
5'h04: begin
cfg_in <= 32'h20000000; // NOOP
cfg_cs_n <= 1'b0;
end
5'h05: begin
cfg_in <= 32'h20000000; // NOOP
state <= (r_we) ? `MBOOT_WRITE : `MBOOT_READ;
cfg_cs_n <= 1'b0;
end
`MBOOT_READ: cfg_in <= { 8'h28, 6'h0, r_addr, 13'h001 };
5'h07: cfg_in <= 32'h20000000; // NOOP
5'h08: cfg_in <= 32'h20000000; // NOOP
`MBOOT_READ: begin
cfg_cs_n <= 1'b0;
cfg_in <= { 8'h28, 6'h0, r_addr, 13'h001 };
end
5'h07: begin
cfg_cs_n <= 1'b0;
cfg_in <= 32'h20000000; // NOOP
end
5'h08: begin
cfg_cs_n <= 1'b0;
cfg_in <= 32'h20000000; // NOOP
end
5'h09: begin // Idle the interface before the read cycle
cfg_cs_n <= 1'b1;
cfg_rdwrn <= 1'b1;
174,12 → 232,18
cfg_rdwrn <= 1'b1;
cfg_in <= 32'h20000000; // NOOP
end
5'h0b: // ... still waiting, cycle two
5'h0b: begin // ... still waiting, cycle two
cfg_in <= 32'h20000000; // NOOP
5'h0c: // ... still waiting, cycle three
cfg_cs_n <= 1'b0;
end
5'h0c: begin // ... still waiting, cycle three
cfg_in <= 32'h20000000; // NOOP
5'h0d: // ... still waiting, cycle four
cfg_cs_n <= 1'b0;
end
5'h0d: begin // ... still waiting, cycle four
cfg_in <= 32'h20000000; // NOOP
cfg_cs_n <= 1'b0;
end
5'h0e: begin // and now our answer is there
cfg_cs_n <= 1'b1;
cfg_rdwrn <= 1'b1;
187,24 → 251,45
//
// Wishbone return
o_wb_ack <= wb_req;
o_wb_data <= cfg_out;
// o_wb_data <= cfg_out; // Independent of state
wb_req <= 1'b0;
//
state <= `MBOOT_DESYNC;
end
`MBOOT_WRITE: // Issue a write command to the given address
`MBOOT_WRITE: begin
// Issue a write command to the given address
cfg_in <= { 8'h30, 6'h0, r_addr, 13'h001 };
5'h10: cfg_in <= r_data; // Write the value
cfg_cs_n <= 1'b0;
end
5'h10: begin
cfg_in <= r_data; // Write the value
cfg_cs_n <= 1'b0;
end
`MBOOT_DESYNC: begin
cfg_cs_n <= 1'b0;
cfg_rdwrn <= 1'b0;
cfg_in <= 32'h20000000; // 1st NOOP
end
5'h12: cfg_in <= 32'h20000000; // 2nd NOOP
5'h13: cfg_in <= 32'h30008001; // Write to CMD register
5'h14: cfg_in <= 32'h0000000d; // DESYNC command
5'h15: cfg_in <= 32'h20000000; // NOOP
5'h16: cfg_in <= 32'h20000000; // NOOP
5'h12: begin
cfg_cs_n <= 1'b0;
cfg_in <= 32'h20000000; // 2nd NOOP
end
5'h13: begin
cfg_cs_n <= 1'b0;
cfg_in <= 32'h30008001; // Write to CMD register
end
5'h14: begin
cfg_cs_n <= 1'b0;
cfg_in <= 32'h0000000d; // DESYNC command
end
5'h15: begin
cfg_cs_n <= 1'b0;
cfg_in <= 32'h20000000; // NOOP
end
5'h16: begin
cfg_cs_n <= 1'b0;
cfg_in <= 32'h20000000; // NOOP
end
5'h17: begin
// Acknowledge the bus transaction, it is now complete
o_wb_ack <= wb_req;
217,7 → 302,7
state <= `MBOOT_IDLE;
end
default: begin
o_wb_ack <= 1'b0;
wb_req <= 1'b0;
cfg_cs_n <= 1'b1;
cfg_rdwrn <= 1'b0;
state <= `MBOOT_IDLE;
224,8 → 309,6
cfg_in <= 32'hffffffff; // DUMMY WORD
end
endcase
end else begin
o_wb_ack <= 1'b0;
end
end
 
259,4 → 342,16
ICAPE2 #(.ICAP_WIDTH("X32")) reconfig(.CLK(slow_clk),
.CSIB(cfg_cs_n), .RDWRB(cfg_rdwrn),
.I(bit_swapped_cfg_in), .O(bit_swapped_cfg_out));
 
assign o_dbg = {
`ifdef DIVIDE_BY_FOUR
slow_clk_counter, clk_stb, clk_stall,
`else
1'b0, slow_clk, clk_stb, clk_stall,
`endif
i_wb_stb, o_wb_ack, cfg_cs_n, cfg_rdwrn,
o_wb_stall, state, 2'h0,
cfg_in[7:0],
cfg_out[7:0] };
 
endmodule
/lleqspi.v
70,7 → 70,7
input i_dir; // 0 -> read, 1 -> write to SPI
input i_recycle; // 0 = 20ns, 1 = 50ns
output reg [31:0] o_word;
output wire o_valid;
output reg o_valid;
output reg o_busy;
// Interface with the QSPI lines
output reg o_sck;
298,38 → 298,42
end
 
`define EXTRA_DELAY
wire rd_input_N, rd_valid_N, r_spd_N;
`ifdef EXTRA_DELAY
reg rd_input_2, rd_valid_2, r_spd_2;
reg [2:0] rd_input_p, rd_valid_p, r_spd_p;
always @(posedge i_clk)
rd_input_2 <= rd_input;
rd_input_p <= { rd_input_p[1:0], rd_input };
always @(posedge i_clk)
rd_valid_2 <= rd_valid;
rd_valid_p <= { rd_valid_p[1:0], rd_valid };
always @(posedge i_clk)
r_spd_2 <= r_spd;
r_spd_p <= { r_spd_p[1:0], r_spd };
 
assign rd_input_N = rd_input_p[2];
assign rd_valid_N = rd_valid_p[2];
assign r_spd_N = r_spd_p[2];
`else
wire rd_input_2, rd_valid_2, r_spd_2;
assign rd_input_2 = rd_input;
assign rd_valid_2 = rd_valid;
assign r_spd_2 = rd_spd;
assign rd_input_N = rd_input;
assign rd_valid_N = rd_valid;
assign r_spd_N = rd_spd;
`endif
 
 
always @(posedge i_clk)
begin
if ((state == `EQSPI_IDLE)||(rd_valid_2))
// if ((state == `EQSPI_IDLE)||(rd_valid_N))
if (o_valid)
r_input <= 31'h00;
else if ((rd_input_2)&&(r_spd_2))
if ((rd_input_N)&&(r_spd_N))
r_input <= { r_input[26:0], i_dat };
else if (rd_input_2)
else if (rd_input_N)
r_input <= { r_input[29:0], i_miso };
 
if ((rd_valid)&&(rd_spd))
if ((rd_valid_N)&&(r_spd_N))
o_word <= { r_input[27:0], i_dat };
else if (rd_valid)
else if (rd_valid_N)
o_word <= { r_input[30:0], i_miso };
o_valid <= rd_valid_N;
end
 
assign o_valid = rd_valid_2;
 
endmodule
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.