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

Subversion Repositories openarty

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 24 to Rev 25
    Reverse comparison

Rev 24 → Rev 25

/openarty/trunk/rtl/memdev.v
39,7 → 39,7
//
module memdev(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);
parameter AW=15, DW=32;
parameter AW=15, DW=32, EXTRACLOCK= 0;
input i_clk, i_wb_cyc, i_wb_stb, i_wb_we;
input [(AW-1):0] i_wb_addr;
input [(DW-1):0] i_wb_data;
47,27 → 47,48
output wire o_wb_stall;
output reg [(DW-1):0] o_wb_data;
 
reg last_wstb, last_stb;
always @(posedge i_clk)
last_wstb <= (i_wb_stb)&&(i_wb_we);
always @(posedge i_clk)
last_stb <= (i_wb_stb);
wire w_wstb, w_stb;
wire [(DW-1):0] w_data;
wire [(AW-1):0] w_addr;
 
reg [(DW-1):0] last_data;
reg [(AW-1):0] last_addr;
always @(posedge i_clk)
last_data <= i_wb_data;
always @(posedge i_clk)
last_addr <= i_wb_addr;
generate
if (EXTRACLOCK == 0)
begin
 
assign w_wstb = (i_wb_stb)&&(i_wb_we);
assign w_stb = i_wb_stb;
assign w_addr = i_wb_addr;
assign w_data = i_wb_data;
 
end else begin
 
reg last_wstb, last_stb;
always @(posedge i_clk)
last_wstb <= (i_wb_stb)&&(i_wb_we);
always @(posedge i_clk)
last_stb <= (i_wb_stb);
 
reg [(DW-1):0] last_data;
reg [(AW-1):0] last_addr;
always @(posedge i_clk)
last_data <= i_wb_data;
always @(posedge i_clk)
last_addr <= i_wb_addr;
 
assign w_wstb = last_wstb;
assign w_stb = last_stb;
assign w_addr = last_addr;
assign w_data = last_data;
end endgenerate
 
reg [(DW-1):0] mem [0:((1<<AW)-1)];
always @(posedge i_clk)
o_wb_data <= mem[last_addr];
o_wb_data <= mem[w_addr];
always @(posedge i_clk)
if (last_wstb)
mem[last_addr] <= last_data;
if (w_wstb)
mem[w_addr] <= w_data;
always @(posedge i_clk)
o_wb_ack <= (last_stb);
o_wb_ack <= (w_stb);
assign o_wb_stall = 1'b0;
 
endmodule
/openarty/trunk/rtl/cpu/div.v
34,8 → 34,8
//
module div(i_clk, i_rst, i_wr, i_signed, i_numerator, i_denominator,
o_busy, o_valid, o_err, o_quotient, o_flags);
parameter BW=32, LGBW = 5;
input i_clk, i_rst;
parameter BW=32, LGBW = 5;
input i_clk, i_rst;
// Input parameters
input i_wr, i_signed;
input [(BW-1):0] i_numerator, i_denominator;
/openarty/trunk/rtl/cpu/zipbones.v
186,7 → 186,7
`endif
);
end else begin
zipcpuhs #(RESET_ADDRESS,ADDRESS_WIDTH,LGICACHE)
zipcpu #(RESET_ADDRESS,ADDRESS_WIDTH,LGICACHE)
thecpu(i_clk, cpu_reset, i_ext_int,
cpu_halt, cmd_clear_pf_cache, cmd_addr[4:0], cpu_dbg_we,
i_dbg_data, cpu_dbg_stall, cpu_dbg_data,
/openarty/trunk/rtl/cpu/zipcpuhs.v
1,6 → 1,6
///////////////////////////////////////////////////////////////////////////////
//
// Filename: zipcpu.v
// Filename: zipcpuhs.v
//
// Project: Zip CPU -- a small, lightweight, RISC CPU soft core
//
7,63 → 7,85
// Purpose: This is the top level module holding the core of the Zip CPU
// together. The Zip CPU is designed to be as simple as possible.
// (actual implementation aside ...) The instruction set is about as
// RISC as you can get, there are only 16 instruction types supported.
// Please see the accompanying spec.pdf file for a description of these
// instructions.
// RISC as you can get, there are only 26 instruction types supported, not
// including the floating point instruction set. Please see the
// accompanying spec.pdf file for a description of these instructions.
//
// All instructions are 32-bits wide. All bus accesses, both address and
// data, are 32-bits over a wishbone bus.
//
// The Zip CPU is fully pipelined with the following pipeline stages:
//
// This version of the ZipCPU has been modified for "high speed" operation.
// By that I mean, it has been modified so that it can handle a high speed
// system clock. The nominal five stage pipeline has therefore been
// broken into nine pieces, as outlined below:
//
// 1. Prefetch, returns the instruction from memory.
//
// 2. Instruction Decode
// 2. Instruction Decode: triplet instructions, VLIW upper half,
// VLIW lower half, and normal instructions
//
// 3. Read Operands
// 3. Instruction Decode: Select among the four types of
// instructions
//
// 4. Apply Instruction
// 4. Read Operand B
//
// 4. Write-back Results
// 5. Read Operand A, add the immediate offset to Operand B
//
// Further information about the inner workings of this CPU may be
// found in the spec.pdf file. (The documentation within this file
// had become out of date and out of sync with the spec.pdf, so look
// to the spec.pdf for accurate and up to date information.)
// 6. 16 ALU operations
//
// 7. Select among ALU results
//
// In general, the pipelining is controlled by three pieces of logic
// per stage: _ce, _stall, and _valid. _valid means that the stage
// holds a valid instruction. _ce means that the instruction from the
// previous stage is to move into this one, and _stall means that the
// instruction from the previous stage may not move into this one.
// The difference between these control signals allows individual stages
// to propagate instructions independently. In general, the logic works
// as:
// 8. Select from ALU, Memory, Divide, FPU results
//
// 9. Write-back Results
//
// assign (n)_ce = (n-1)_valid && (~(n)_stall)
// Further information about the ZipCPU may be found in the spec.pdf file.
// (The documentation within this file is likely to become out of date
// and out of sync with the spec.pdf, so look to the spec.pdf for
// accurate and up to date information.)
//
//
// always @(posedge i_clk)
// if ((i_rst)||(clear_pipeline))
// (n)_valid = 0
// else if (n)_ce
// (n)_valid = 1
// else if (n+1)_ce
// (n)_valid = 0
// A note about pipelining. The approach used to accommodate pipelining
// in this implementation assumes that if will be impossible to tell if
// a particular stage will stall until the logic for that stage completes.
// There is no time, therefore, for the stall logic to ripple from the
// end of the pipeline to the beginning. At best, it can ripple from
// one stage to the next. Stall logic, therefore, is latched in a
// FLIP-FLOP, rather than done in a combinatorial fashion. Hopefully,
// you'll have a copy of the stall logic slides. If not, here's the
// outline of how stalls will be done:
//
// assign (n)_stall = ( (n-1)_valid && ( pipeline hazard detection ) )
// || ( (n)_valid && (n+1)_stall );
// assign (n)_slp = // stall logic for location n, based upon the prior
// // stages info
// assign (n)_slc = // stall logic for location n, based upon a copy of
// // what was in the prior stage
//
// and ...
//
// // We'll shorten _valid to _v, _stall to _s, _copy to _c
// always @(posedge i_clk)
// if (n)_ce
// (n)_variable = ... whatever logic for this stage
// if ((i_rst)||(clear_pipeline)
// (n)_v = 0;
// else if (!(n)_stall)
// (n)_v = ( (n-1)_v && (!(n)_slp) );
// else
// (n)_v = ( !(n)_slc );
//
// Note that a stage can stall even if no instruction is loaded into
// it.
// always @(posedge i_clk)
// if ((i_rst)||(clear_pipeline)
// (n)_s = 1'b0;
// else if (!(n)_s)
// (n)_s = ((n-1)_v) && ( (n)_slp || (n+1)_s );
// else
// (n)_s = ( (n)_slc || (n+1)_s );
//
// always @(posedge i_clk)
// if ((n)_s)
// (n)_data = PROCESS[(n)_c];
// // Can't chnge copy if not stalled
// else
// (n)_data = PROCESS[(n-1)_data];
// (n)_c <= (n-1)_data;
//
//
// Creator: Dan Gisselquist, Ph.D.
239,7 → 261,7
wire [31:0] pf_data;
wire [31:0] instruction;
wire [(AW-1):0] instruction_pc;
wire pf_valid, instruction_gie, pf_illegal;
wire pf_v, instruction_gie, pf_illegal;
 
//
//
257,7 → 279,7
dcdF_wr, dcd_gie, dcd_break, dcd_lock,
dcd_pipe, dcd_ljmp;
reg [1:0] r_dcdvalid;
wire dcd_valid;
wire dcd_v;
wire [(AW-1):0] dcd_pc;
wire [31:0] dcd_I;
wire dcd_zI; // true if dcdI == 0
276,7 → 298,7
//
//
// Now, let's read our operands
reg opa_valid, opa_DV, opa_FP, opa_ALU, opa_M,
reg opa_v, opa_DV, opa_FP, opa_ALU, opa_M,
opa_rA, opa_rB;
reg [4:0] alu_reg;
reg [3:0] opa_opn;
292,12 → 314,7
// Some pipeline control wires
reg opa_A_alu, opa_A_mem;
reg opa_B_alu, opa_B_mem;
`ifdef OPT_ILLEGAL_INSTRUCTION
reg opa_illegal;
`else
wire opa_illegal;
assign opa_illegal = 1'b0;
`endif
reg opa_break;
reg opa_lock;
 
310,8 → 327,8
//
// Now, let's read our operands
reg [3:0] opb_opn;
reg opb_valid, opb_valid_mem, opb_valid_alu;
reg opb_valid_div, opb_valid_fpu;
reg opb_v, opb_v_mem, opb_v_alu;
reg opb_v_div, opb_v_fpu;
reg [4:0] opb_R;
reg [31:0] r_opb_A, r_opb_B;
reg [(AW-1):0] opb_pc;
324,12 → 341,7
// Some pipeline control wires
reg opb_A_alu, opb_A_mem;
reg opb_B_alu, opb_B_mem;
`ifdef OPT_ILLEGAL_INSTRUCTION
reg opb_illegal;
`else
wire opb_illegal;
assign opb_illegal = 1'b0;
`endif
reg opb_break;
reg opb_lock;
 
340,14 → 352,15
// Variable declarations
//
//
reg stage_busy;
reg [(AW-1):0] alu_pc;
reg r_alu_pc_valid, mem_pc_valid;
wire alu_pc_valid;
reg r_alu_pc_v, mem_pc_v;
wire alu_pc_v;
wire alu_phase;
wire alu_ce, alu_stall;
wire [31:0] alu_result;
wire [3:0] alu_flags;
wire alu_valid, alu_busy;
wire alu_v, alu_busy;
wire set_cond;
reg alu_wr, alF_wr, alu_gie;
wire alu_illegal_op;
357,7 → 370,7
 
wire mem_ce, mem_stalled;
wire mem_pipe_stalled;
wire mem_valid, mem_ack, mem_stall, mem_err, bus_err,
wire mem_v, mem_ack, mem_stall, mem_err, bus_err,
mem_cyc_gbl, mem_cyc_lcl, mem_stb_gbl, mem_stb_lcl, mem_we;
wire [4:0] mem_wreg;
 
365,18 → 378,18
wire [(AW-1):0] mem_addr;
wire [31:0] mem_data, mem_result;
 
wire div_ce, div_error, div_busy, div_valid;
wire div_ce, div_error, div_busy, div_v;
wire [31:0] div_result;
wire [3:0] div_flags;
 
assign div_ce = (master_ce)&&(~clear_pipeline)&&(opb_valid_div)
assign div_ce = (master_ce)&&(~clear_pipeline)&&(opb_v_div)
&&(~stage_busy)&&(set_cond);
 
wire fpu_ce, fpu_error, fpu_busy, fpu_valid;
wire fpu_ce, fpu_error, fpu_busy, fpu_v;
wire [31:0] fpu_result;
wire [3:0] fpu_flags;
 
assign fpu_ce = (master_ce)&&(~clear_pipeline)&&(opb_valid_fpu)
assign fpu_ce = (master_ce)&&(~clear_pipeline)&&(opb_v_fpu)
&&(~stage_busy)&&(set_cond);
 
//
408,46 → 421,42
//
// PIPELINE STAGE #2 :: Instruction Decode
// Calculate stall conditions
assign dcd_ce = ((~dcd_valid)||(~dcd_stalled))&&(~clear_pipeline);
assign dcd_ce = ((~dcd_v)||(~dcd_stalled))&&(~clear_pipeline);
 
assign dcd_stalled = (dcd_valid)&&(op_stall);
assign dcd_stalled = (dcd_v)&&(opa_stall);
//
// PIPELINE STAGE #3 :: Read Operands
// Calculate stall conditions
wire op_lock_stall;
assign op_stall = (opvalid)&&( // Only stall if we're loaded w/validins
// Stall if we're stopped, and not allowed to execute
// an instruction
// (~master_ce) // Already captured in alu_stall
//
// Stall if going into the ALU and the ALU is stalled
// i.e. if the memory is busy, or we are single
// stepping. This also includes our stalls for
// op_break and op_lock, so we don't need to
// include those as well here.
// This also includes whether or not the divide or
// floating point units are busy.
(alu_stall)
//
// Stall if we are going into memory with an operation
// that cannot be pipelined, and the memory is
// already busy
||(mem_stalled) // &&(opvalid_mem) part of mem_stalled
)
||(dcd_valid)&&(
// Stall if we need to wait for an operand A
// to be ready to read
(dcdA_stall)
assign opa_stall_slp = (
// Likewise for B, also includes logic
// regarding immediate offset (register must
// be in register file if we need to add to
// an immediate)
||(dcdB_stall)
(((dcdB_rd)&&(~dcd_zI))
&&((opa_v)&&(opb_R == dcdB)
||(mem_rdbusy)
||((div_busy)&&(div_R == dcdB))
||((fpu_busy)&&(fpu_R == dcdB))
||((alua_v)&&(alua_R==dcdB))
||((alub_v)&&(alub_R==dcdB))
||((alu_busy))
&&(
// 1.
((~dcd_zI)&&(
((opb_R == dcdB)&&(opb_wR))
||((mem_rdbusy)&&(~dcd_pipe))
))
// 2.
||((opF_wr)&&(dcdB_cc))
)))
// Or if we need to wait on flags to work on the
// CC register
||(dcdF_stall)
||(((~dcdF[3])
||((dcd_rA)&&(dcdA_cc))
||((dcd_rB)&&(dcdB_cc)))
&&(opb_v)&&(opb_ccR))
);
assign opa_ce = ((dcd_valid)||(dcd_illegal))&&(~opa_stall);
 
//
// PIPELINE STAGE #4 :: ALU / Memory
462,34 → 471,30
// 4. Last case: Stall if we would otherwise move a break instruction
// through the ALU. Break instructions are not allowed through
// the ALU.
assign alu_stall = (((~master_ce)||(mem_rdbusy)||(alu_busy))&&(opvalid_alu)) //Case 1&2
// Old case #3--this isn't an ALU stall though ...
||((opvalid_alu)&&(wr_reg_ce)&&(wr_reg_id[4] == op_gie)
&&(wr_write_cc)) // Case 3
||((opvalid)&&(op_lock)&&(op_lock_stall))
||((opvalid)&&(op_break))
||(div_busy)||(fpu_busy);
assign alu_ce = (master_ce)&&(stage_ce)&&(opvalid_alu)&&(~clear_pipeline);
assign alu_stall_clp = (~master_ce);
assign alu_stall_cls = (~master_ce);
always @(posedge i_clk)
stage_busy <= (alu_ce)||(mem_ce)||(fpu_ce)||(div_ce)
||(alu_busy)||(mem_rdbusy)||(fpu_busy)||(div_busy);
assign stage_ce = (~div_busy)&&(~alu_busy)&&(~mem_rdbusy)&&(~fpu_busy);
//
 
//
// Note: if you change the conditions for mem_ce, you must also change
// alu_pc_valid.
// alu_pc_v.
//
assign mem_ce = (master_ce)&&(opvalid_mem)&&(~mem_stalled)
assign mem_ce = (master_ce)&&(opb_v_mem)&&(~mem_stalled)
&&(~clear_pipeline);
assign mem_stalled = (~master_ce)||(alu_busy)||((opvalid_mem)&&(
(mem_pipe_stalled)
||((~op_pipe)&&(mem_busy))
||(div_busy)
||(fpu_busy)
// Stall waiting for flags to be valid
// Or waiting for a write to the PC register
// Or CC register, since that can change the
// PC as well
||((wr_reg_ce)&&(wr_reg_id[4] == op_gie)
&&((wr_write_pc)||(wr_write_cc)))));
assign mem_stall_clp = (~master_ce)||(alu_busy)||(div_busy)||(fpu_busy)
||(wr_write_pc)||(wr_write_cc)
||((opb_v_mem)&&(
(mem_pipe_stalled)
||((~opb_pipe)&&(mem_busy))));
assign mem_stall_cls = (~master_ce)||(alu_busy)||(div_busy)||(fpu_busy)
||(wr_write_pc)||(wr_write_cc)
||((cp_opb_v_mem)&&(
(mem_pipe_stalled)
||((~cp_opb_pipe)&&(mem_busy))));
 
 
//
504,7 → 509,7
~dcd_stalled,
((dcd_early_branch)&&(~clear_pipeline))
? dcd_branch_pc:pf_pc,
instruction, instruction_pc, pf_valid,
instruction, instruction_pc, pf_v,
pf_cyc, pf_stb, pf_we, pf_addr, pf_data,
pf_ack, pf_stall, pf_err, i_wb_data,
pf_illegal);
513,7 → 518,7
//
// The ifastdec decoder takes two clocks to decode an instruction.
// Therefore, to determine if a decoded instruction is valid, we
// need to wait two clocks from pf_valid. Hence, we dump this into
// need to wait two clocks from pf_v. Hence, we dump this into
// a pipeline below.
//
initial r_dcdvalid = 2'b00;
521,21 → 526,21
if ((i_rst)||(clear_pipeline)||(w_clear_icache))
r_dcdvalid <= 2'b00;
else if (dcd_ce)
r_dcdvalid <= { r_dcdvalid[0], pf_valid };
r_dcdvalid <= { r_dcdvalid[0], pf_v };
else if (opa_ce)
r_dcdvalid <= 1'b0;
assign dcd_valid = r_dcdvalid[1];
assign dcd_v = r_dcdvalid[1];
 
ifastdec #(AW, IMPLEMENT_MPY, EARLY_BRANCHING, IMPLEMENT_DIVIDE,
IMPLEMENT_FPU)
instruction_decoder(i_clk, (i_rst)||(clear_pipeline),
dcd_ce, dcd_stalled, instruction, instruction_gie,
instruction_pc, pf_valid, pf_illegal, dcd_phase,
instruction_pc, pf_v, pf_illegal, dcd_phase,
dcd_illegal, dcd_pc, dcd_gie,
{ dcdR_cc, dcdR_pc, dcd_iR },
{ dcdA_cc, dcdA_pc, dcd_iA },
{ dcdB_cc, dcdB_pc, dcd_iB },
dcd_I, dcd_zI, dcdF, dcdF_wr, dcdOp,
{ dcd_Rcc, dcd_Rpc, dcd_iR },
{ dcd_Acc, dcd_Apc, dcd_iA },
{ dcd_Bcc, dcd_Bpc, dcd_iB },
dcd_I, dcd_zI, dcd_F, dcd_wF, dcdOp,
dcdALU, dcdM, dcdDV, dcdFP, dcd_break, dcd_lock,
dcd_wR,dcd_rA, dcd_rB,
dcd_early_branch,
542,9 → 547,14
dcd_branch_pc, dcd_ljmp,
dcd_pipe);
 
reg r_op_pipe;
//
//
// PIPELINE STAGE #3 :: Read Operands (Registers)
//
//
 
initial r_op_pipe = 1'b0;
reg opa_pipe;
initial opa_pipe = 1'b0;
// To be a pipeable operation, there must be
// two valid adjacent instructions
// Both must be memory instructions
555,20 → 565,78
// However ... we need to know this before this clock, hence this is
// calculated in the instruction decoder.
always @(posedge i_clk)
if (op_ce)
r_op_pipe <= dcd_pipe;
else if (mem_ce) // Clear us any time an op_ is clocked in
r_op_pipe <= 1'b0;
assign op_pipe = r_op_pipe;
if (!opa_stall)
begin
opa_v <= dcdvalid&&(~opa_stall_slp);
opa_stall <= (dcdvalid)&&(opa_stall_slp);
opa_pipe <= dcd_pipe;
 
//
//
// PIPELINE STAGE #3 :: Read Operands (Registers)
//
//
assign w_opA = regset[dcd_iA];
assign w_opB = regset[dcd_iB];
opa_wR <= dcd_wR;
{ opa_Acc, opa_Apc, opa_iA, opa_rA }
<= { dcd_Acc, dcd_Apc, dcd_iA, dcd_rA };
{ opa_Bcc, opa_Bpc, opa_iB, opa_rB }
<= { dcd_Bcc, dcd_Bpc, dcd_iB, dcd_rB };
 
// Register A
if (dcd_Apc)
opa_vA <= (dcd_iA[4]==dcd_gie) ? dcd_pc
: (dcd_iA)?upc : ipc;
else if (dcd_Acc)
opa_vA <= (dcd_iA[4])?user_flags_reg
: supervisor_flags_reg;
else
opa_vA <= regset[dcd_iA];
 
// Register B
if (!dcd_rB)
opa_vB <= 32'h00;
else if (dcd_Bpc)
opa_vB <= (dcd_iB[4]==dcd_gie) ? dcd_pc
: (dcd_iB)?upc : ipc;
else if (dcd_Bcc)
opa_vB <= (dcd_iB[4])?user_flags_reg
: supervisor_flags_reg;
else
opa_vB <= regset[dcd_iB];
 
// Copy
cp_opa_pc <= dcd_pc;
cp_opa_gie <= dcd_gie;
cp_opa_pipe <= dcd_pipe;
{ cp_opa_Rcc, cp_opa_Rpc, cp_opa_iR }
<= { dcd_Rcc, dcd_Rpc, dcd_iR };
{ cp_opa_Acc, cp_opa_Apc, cp_opa_iA }
<= { dcd_Acc, dcd_Apc, dcd_iA };
{ cp_opa_Bcc, cp_opa_Bpc, cp_opa_iB }
<= { dcd_Bcc, dcd_Bpc, dcd_iB };
end else begin
opa_v <= (~opa_stall_slc);
opa_stall <= (opa_stall_slc);
opa_pipe <= cp_opa_pipe;
 
// Register A
if (cp_opa_Apc)
opa_vA <= (cp_opa_iA[4]==cp_opa_gie) ? cp_opa_pc
: (cp_opa_iA)?upc : ipc;
else if (dcd_Acc)
opa_vA <= (cp_opa_iA[4])?user_flags_reg
: supervisor_flags_reg;
else
opa_vA <= regset[cp_opa_iA];
 
// Register B
if (!cp_opa_rB)
opa_vB <= 32'h00;
else if (cp_opa_Bpc)
opa_vB <= (cp_opa_iB[4]==cp_opa_gie) ? cp_opa_pc
: (cp_opa_iB)?upc : ipc;
else if (cp_opa_Bcc)
opa_vB <= (cp_opa_iB[4])?user_flags_reg
: supervisor_flags_reg;
else
opa_vB <= regset[cp_opa_iB];
end
 
wire [8:0] w_cpu_info;
assign w_cpu_info = {
`ifdef OPT_ILLEGAL_INSTRUCTION
601,28 → 669,9
`endif
};
 
wire [31:0] w_pcA_v;
generate
if (AW < 32)
assign w_pcA_v = {{(32-AW){1'b0}}, (dcd_iA[4] == dcd_gie)?dcd_pc:upc };
else
assign w_pcA_v = (dcd_iA[4] == dcd_gie)?dcd_pc:upc;
endgenerate
 
reg [4:0] opa_Aid, opa_Bid;
reg opa_Ard, opa_Brd;
always @(posedge i_clk)
if (opa_ce)
begin
opa_iA <= dcd_iA;
opa_iB <= dcd_iB;
opa_rA <= dcd_rA;
opa_rB <= dcd_rB;
end
 
always @(posedge i_clk)
if (opa_ce)
begin
if ((wr_reg_ce)&&(wr_reg_id == dcd_iA))
r_opA <= wr_gpreg_vl;
else if (dcdA_pc)
707,39 → 756,39
end // Bit order is { (flags_not_used), VNCZ mask, VNCZ value }
assign opb_F = { r_opb_F[3], r_opb_F[5], r_opb_F[1], r_opb_F[4:0] };
 
wire w_opa_valid;
wire w_opa_v;
always @(posedge i_clk)
if (i_rst)
opa_valid <= 1'b0;
opa_v <= 1'b0;
else if (opa_ce)
opa_valid <= ((dcd_valid)||(dcd_illegal))&&(~clear_pipeline);
opa_v <= ((dcd_v)||(dcd_illegal))&&(~clear_pipeline);
 
always @(posedge i_clk)
if ((i_rst)||(clear_pipeline))
begin
opa_valid <= 1'b0;
opa_v <= 1'b0;
end else if (opa_ce)
begin
opa_valid <=(dcd_valid);
opa_M <= (dcd_valid)&&(opa_M )&&(~opa_illegal);
opa_DV <= (dcd_valid)&&(opa_DV )&&(~opa_illegal);
opa_FP <= (dcd_valid)&&(opa_FP )&&(~opa_illegal);
opa_v <=(dcd_v);
opa_M <= (dcd_v)&&(opa_M )&&(~opa_illegal);
opa_DV <= (dcd_v)&&(opa_DV )&&(~opa_illegal);
opa_FP <= (dcd_v)&&(opa_FP )&&(~opa_illegal);
end else if (opb_ce)
opa_valid <= 1'b0;
opa_v <= 1'b0;
 
initial opb_valid = 1'b0;
initial opb_valid_alu = 1'b0;
initial opb_valid_mem = 1'b0;
initial opb_valid_div = 1'b0;
initial opb_valid_fpu = 1'b0;
initial opb_v = 1'b0;
initial opb_v_alu = 1'b0;
initial opb_v_mem = 1'b0;
initial opb_v_div = 1'b0;
initial opb_v_fpu = 1'b0;
always @(posedge i_clk)
if ((i_rst)||(clear_pipeline))
begin
opb_valid <= 1'b0;
opb_valid_alu <= 1'b0;
opb_valid_mem <= 1'b0;
opb_valid_div <= 1'b0;
opb_valid_fpu <= 1'b0;
opb_v <= 1'b0;
opb_v_alu <= 1'b0;
opb_v_mem <= 1'b0;
opb_v_div <= 1'b0;
opb_v_fpu <= 1'b0;
end else if (opb_ce)
begin
// Do we have a valid instruction?
750,18 → 799,18
// Hence, the test on dcd_stalled here. If we must
// wait until our operands are valid, then we aren't
// valid yet until then.
opb_valid <= (opa_valid);
opb_valid_alu <=(opa_valid)&&((opa_ALU)||(opa_illegal));
opb_valid_mem <= (opa_valid)&&(opa_M )&&(~opa_illegal);
opb_valid_div <= (opa_valid)&&(opa_DV )&&(~opa_illegal);
opb_valid_fpu <= (opa_valid)&&(opa_FP )&&(~opa_illegal);
opb_v <= (opa_v);
opb_v_alu <=(opa_v)&&((opa_ALU)||(opa_illegal));
opb_v_mem <= (opa_v)&&(opa_M )&&(~opa_illegal);
opb_v_div <= (opa_v)&&(opa_DV )&&(~opa_illegal);
opb_v_fpu <= (opa_v)&&(opa_FP )&&(~opa_illegal);
end else if ((clear_pipeline)||(stage_ce))
begin
opb_valid <= 1'b0;
opb_valid_alu <= 1'b0;
opb_valid_mem <= 1'b0;
opb_valid_div <= 1'b0;
opb_valid_fpu <= 1'b0;
opb_v <= 1'b0;
opb_v_alu <= 1'b0;
opb_v_mem <= 1'b0;
opb_v_div <= 1'b0;
opb_v_fpu <= 1'b0;
end
 
initial op_break = 1'b0;
769,7 → 818,7
if (i_rst) opb_break <= 1'b0;
else if (opb_ce)
opb_break <= (opa_break)&&((break_en)||(~opa_gie));
else if ((clear_pipeline)||(~opb_valid))
else if ((clear_pipeline)||(~opb_v))
opb_break <= 1'b0;
 
reg r_op_lock, r_op_lock_stall;
779,8 → 828,8
if (i_rst)
r_op_lock_stall <= 1'b0;
else
r_op_lock_stall <= (~opvalid)||(~op_lock)
||(~dcd_valid)||(~pf_valid);
r_op_lock_stall <= (~opb_v)||(~opb_lock)
||(~opa_v)||(~dcd_v)||(~pf_v);
 
assign op_lock_stall = r_op_lock_stall;
 
832,7 → 881,7
opa_ccR <= (dcdR_cc)&&(dcd_wR)&&(dcd_iR[4]==dcd_gie);
opa_gie <= dcd_gie;
//
opa_pc <= dcd_valid;
opa_pc <= dcd_v;
opa_rA <= dcd_;
opa_rB <= dcd_;
end
863,12 → 912,12
assign opA = r_opA;
 
assign dcdA_stall = (dcd_rA) // &&(dcdvalid) is checked for elsewhere
&&((opa_valid)||(mem_rdbusy)
&&((opa_v)||(mem_rdbusy)
||(div_busy)||(fpu_busy))
&&((opF_wr)&&(dcdA_cc));
 
assign dcdB_stall = (dcdB_rd)
&&((opa_valid)||(mem_rdbusy)
&&((opa_v)||(mem_rdbusy)
||(div_busy)||(fpu_busy)||(alu_busy))
&&(
// 1.
882,7 → 931,7
assign dcdF_stall = ((~dcdF[3])
||((dcd_rA)&&(dcdA_cc))
||((dcd_rB)&&(dcdB_cc)))
&&(opvalid)&&(opb_ccR);
&&(opb_v)&&(opb_ccR);
//
//
// PIPELINE STAGE #4 :: Apply Instruction
889,12 → 938,12
//
//
fastops fastalu(i_clk, i_rst, alu_ce,
(opb_valid_alu), opb_opn, opb_A, opb_B,
alu_result, alu_flags, alu_valid, alu_illegal_op,
(opb_v_alu), opb_opn, opb_A, opb_B,
alu_result, alu_flags, alu_v, alu_illegal_op,
alu_busy);
 
div thedivide(i_clk, (i_rst)||(clear_pipeline), div_ce, opb_opn[0],
opb_A, opb_B, div_busy, div_valid, div_error, div_result,
opb_A, opb_B, div_busy, div_v, div_error, div_result,
div_flags);
 
generate
902,18 → 951,18
begin
//
// sfpu thefpu(i_clk, i_rst, fpu_ce,
// opA, opB, fpu_busy, fpu_valid, fpu_err, fpu_result,
// opA, opB, fpu_busy, fpu_v, fpu_err, fpu_result,
// fpu_flags);
//
assign fpu_error = 1'b0; // Must only be true if fpu_valid
assign fpu_error = 1'b0; // Must only be true if fpu_v
assign fpu_busy = 1'b0;
assign fpu_valid = 1'b0;
assign fpu_v = 1'b0;
assign fpu_result= 32'h00;
assign fpu_flags = 4'h0;
end else begin
assign fpu_error = 1'b0;
assign fpu_busy = 1'b0;
assign fpu_valid = 1'b0;
assign fpu_v = 1'b0;
assign fpu_result= 32'h00;
assign fpu_flags = 4'h0;
end endgenerate
976,21 → 1025,21
else if (stage_ce)
alu_illegal <= opb_illegal;
 
initial r_alu_pc_valid = 1'b0;
initial mem_pc_valid = 1'b0;
initial r_alu_pc_v = 1'b0;
initial mem_pc_v = 1'b0;
always @(posedge i_clk)
if (i_rst)
r_alu_pc_valid <= 1'b0;
r_alu_pc_v <= 1'b0;
else if (adf_ce_unconditional)//Includes&&(~alu_clear_pipeline)
r_alu_pc_valid <= 1'b1;
r_alu_pc_v <= 1'b1;
else if (((~alu_busy)&&(~div_busy)&&(~fpu_busy))||(clear_pipeline))
r_alu_pc_valid <= 1'b0;
assign alu_pc_valid = (r_alu_pc_valid)&&((~alu_busy)&&(~div_busy)&&(~fpu_busy));
r_alu_pc_v <= 1'b0;
assign alu_pc_v = (r_alu_pc_v)&&((~alu_busy)&&(~div_busy)&&(~fpu_busy));
always @(posedge i_clk)
if (i_rst)
mem_pc_valid <= 1'b0;
mem_pc_v <= 1'b0;
else
mem_pc_valid <= (mem_ce);
mem_pc_v <= (mem_ce);
 
wire bus_lock;
 
1001,7 → 1050,7
r_bus_lock <= 2'b00;
else if ((opb_ce)&&(opb_lock))
r_bus_lock <= 2'b11;
else if ((|r_bus_lock)&&((~opb_valid_mem)||(~opb_ce)))
else if ((|r_bus_lock)&&((~opb_v_mem)||(~opb_ce)))
r_bus_lock <= r_bus_lock + 2'b11; // r_bus_lock -= 1
assign bus_lock = |r_bus_lock;
 
1008,7 → 1057,7
pipemem #(AW,IMPLEMENT_LOCK) domem(i_clk, i_rst,(mem_ce)&&(set_cond), bus_lock,
(opb_opn[0]), opb_B, opb_A, opb_R,
mem_busy, mem_pipe_stalled,
mem_valid, bus_err, mem_wreg, mem_result,
mem_v, bus_err, mem_wreg, mem_result,
mem_cyc_gbl, mem_cyc_lcl,
mem_stb_gbl, mem_stb_lcl,
mem_we, mem_addr, mem_data,
1053,10 → 1102,10
 
// 1. Will we need to write a register?
always @(posedge i_clk)
r_wr_ce <= (dbgv)||(mem_valid)
r_wr_ce <= (dbgv)||(mem_v)
||((~clear_pipeline)&&(~alu_illegal)
&&(((alu_wr)&&(alu_valid))
||(div_valid)||(fpu_valid)));
&&(((alu_wr)&&(alu_v))
||(div_v)||(fpu_v)));
assign wr_reg_ce = r_wr_ce;
 
// 2. Did the ALU/MEM/DIV/FPU stage produce an error of any type?
1067,19 → 1116,19
// these will be causes for an interrupt on the next clock after this
// one.
always @(posedge i_clk)
r_wr_err <= ((div_valid)&&(div_error))
||((fpu_valid)&&(fpu_error))
||((alu_pc_valid)&&(alu_illegal))
r_wr_err <= ((div_v)&&(div_error))
||((fpu_v)&&(fpu_error))
||((alu_pc_v)&&(alu_illegal))
||(bus_err);
reg r_wr_illegal;
always @(posedge i_clk)
r_wr_illegal <= (alu_pc_valid)&&(alu_illegal);
r_wr_illegal <= (alu_pc_v)&&(alu_illegal);
 
// Which register shall be written?
// Note that the alu_reg is the register to write on a divide or
// FPU operation.
always @(posedge i_clk)
r_wr_reg <= (alu_wr|div_valid|fpu_valid)?alu_reg:mem_wreg;
r_wr_reg <= (alu_wr|div_v|fpu_v)?alu_reg:mem_wreg;
assign wr_reg_id = r_wr_reg;
 
// Are we writing to the CC register?
1091,9 → 1140,9
 
// What value to write?
always @(posedge i_clk)
r_wr_val <= ((mem_valid) ? mem_result
:((div_valid|fpu_valid))
? ((div_valid) ? div_result:fpu_result)
r_wr_val <= ((mem_v) ? mem_result
:((div_v|fpu_v))
? ((div_v) ? div_result:fpu_result)
:((dbgv) ? dbg_val : alu_result));
assign wr_gpreg_vl = r_wr_val;
assign wr_spreg_vl = r_wr_val;
1102,17 → 1151,17
reg r_wr_flags_ce;
initial r_wr_flags_ce = 1'b0;
always @(posedge i_clk)
r_wr_flags_ce <= ((alF_wr)||(div_valid)||(fpu_valid))
r_wr_flags_ce <= ((alF_wr)||(div_v)||(fpu_v))
&&(~clear_pipeline)&&(~alu_illegal);
assign wr_flags_ce = r_wr_flags_ce;
 
reg [3:0] r_wr_newflags;
always @(posedge i_clk)
if (div_valid)
if (div_v)
r_wr_newflags <= div_flags;
else if (fpu_valid)
else if (fpu_v)
r_wr_newflags <= fpu_flags;
else // if (alu_valid)
else // if (alu_v)
r_wr_newflags <= alu_flags;
 
reg r_wr_gie;
1119,14 → 1168,14
always @(posedge i_clk)
r_wr_gie <= (~dbgv)&&(alu_gie);
 
reg r_wr_pc_valid;
initial r_wr_pc_valid = 1'b0;
reg r_wr_pc_v;
initial r_wr_pc_v = 1'b0;
always @(posedge i_clk)
r_wr_pc_valid <= ((alu_pc_valid)&&(~clear_pipeline))
||(mem_pc_valid);
r_wr_pc_v <= ((alu_pc_v)&&(~clear_pipeline))
||(mem_pc_v);
reg [(AW-1):0] r_wr_pc;
always @(posedge i_clk)
r_wr_pc <= alu_pc; // (alu_pc_valid)?alu_pc : mem_pc;
r_wr_pc <= alu_pc; // (alu_pc_v)?alu_pc : mem_pc;
 
////
//
1214,7 → 1263,7
initial fast_interrupt = 1'b0;
always @(posedge i_clk) // 12 inputs
fast_interrupt <= ((gie)||(alu_gie))&&(
((r_wr_pc_valid)&&(step)&&(~alu_phase)&&(~bus_lock))
((r_wr_pc_v)&&(step)&&(~alu_phase)&&(~bus_lock))
// Or ... if we encountered some form of error in our
// instruction ...
||(r_wr_err)
1282,7 → 1331,7
step <= 1'b0;
else if ((wr_reg_ce)&&(~alu_gie)&&(wr_reg_id[4])&&(wr_write_cc))
step <= wr_spreg_vl[`CPU_STEP_BIT];
else if (((alu_pc_valid)||(mem_pc_valid))&&(step)&&(gie))
else if (((alu_pc_v)||(mem_pc_v))&&(step)&&(gie))
step <= 1'b0;
 
 
1348,7 → 1397,7
else if ((dbgv)&&(wr_reg_id == {1'b0, `CPU_CC_REG})
&&(~wr_spreg_vl[`CPU_DIVERR_BIT]))
r_idiv_err_flag <= 1'b0;
else if ((div_error)&&(div_valid)&&(~r_wr_gie))
else if ((div_error)&&(div_v)&&(~r_wr_gie))
r_idiv_err_flag <= 1'b1;
// User divide (by zero) error flag -- if ever set, it will
// cause a sudden switch interrupt to supervisor mode.
1362,7 → 1411,7
&&(~wr_spreg_vl[`CPU_DIVERR_BIT])
&&(wr_reg_id[4])&&(wr_write_cc))
r_udiv_err_flag <= 1'b0;
else if ((div_error)&&(r_wr_gie)&&(div_valid))
else if ((div_error)&&(r_wr_gie)&&(div_v))
r_udiv_err_flag <= 1'b1;
 
assign idiv_err_flag = r_idiv_err_flag;
1381,7 → 1430,7
else if ((dbgv)&&(wr_reg_id == {1'b0, `CPU_CC_REG})
&&(~wr_spreg_vl[`CPU_FPUERR_BIT]))
r_ifpu_err_flag <= 1'b0;
else if ((fpu_error)&&(fpu_valid)&&(~r_wr_gie))
else if ((fpu_error)&&(fpu_v)&&(~r_wr_gie))
r_ifpu_err_flag <= 1'b1;
// User floating point error flag -- if ever set, it will cause
// a sudden switch interrupt to supervisor mode.
1395,7 → 1444,7
&&(~wr_spreg_vl[`CPU_FPUERR_BIT])
&&(wr_reg_id[4])&&(wr_write_cc))
r_ufpu_err_flag <= 1'b0;
else if ((fpu_error)&&(r_wr_gie)&&(fpu_valid))
else if ((fpu_error)&&(r_wr_gie)&&(fpu_v))
r_ufpu_err_flag <= 1'b1;
 
assign ifpu_err_flag = r_ifpu_err_flag;
1413,7 → 1462,7
always @(posedge i_clk)
if (i_rst)
r_ihalt_phase <= 1'b0;
else if ((~alu_gie)&&(alu_pc_valid)&&(~clear_pipeline))
else if ((~alu_gie)&&(alu_pc_v)&&(~clear_pipeline))
r_ihalt_phase <= alu_phase;
always @(posedge i_clk)
if (r_wr_gie)
1442,8 → 1491,8
if ((wr_reg_ce)&&(wr_reg_id[4])&&(wr_write_pc))
upc <= wr_spreg_vl[(AW-1):0];
else if ((r_wr_gie)&&
(((alu_pc_valid)&&(~clear_pipeline))
||(mem_pc_valid)))
(((alu_pc_v)&&(~clear_pipeline))
||(mem_pc_v)))
upc <= alu_pc;
 
always @(posedge i_clk)
1452,8 → 1501,8
else if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_pc))
ipc <= wr_spreg_vl[(AW-1):0];
else if ((~r_wr_gie)&&
(((alu_pc_valid)&&(~clear_pipeline))
||(mem_pc_valid)))
(((alu_pc_v)&&(~clear_pipeline))
||(mem_pc_v)))
ipc <= alu_pc;
 
always @(posedge i_clk)
1468,12 → 1517,12
`ifdef OPT_PIPELINED
else if ((dcd_early_branch)&&(~clear_pipeline))
pf_pc <= dcd_branch_pc + 1;
else if ((new_pc)||((~dcd_stalled)&&(pf_valid)))
else if ((new_pc)||((~dcd_stalled)&&(pf_v)))
pf_pc <= pf_pc + {{(AW-1){1'b0}},1'b1};
`else
else if ((alu_gie==gie)&&(
((alu_pc_valid)&&(~clear_pipeline))
||(mem_pc_valid)))
((alu_pc_v)&&(~clear_pipeline))
||(mem_pc_v)))
pf_pc <= alu_pc;
`endif
 
1547,7 → 1596,7
(~pf_cyc)&&(~mem_busy)&&(~alu_busy)
&&(~div_busy)&&(~fpu_busy)
// Operations must either be valid, or illegal
&&((opvalid)||(i_rst)||(dcd_illegal))
&&((opb_v)||(i_rst)||(dcd_illegal))
// Decode stage must be either valid, in reset, or ill
&&((dcdvalid)||(i_rst)||(pf_illegal)));
assign o_dbg_stall = ~r_halted;
1559,8 → 1608,8
//
//
assign o_op_stall = (master_ce)&&(op_stall);
assign o_pf_stall = (master_ce)&&(~pf_valid);
assign o_i_count = (alu_pc_valid)&&(~clear_pipeline);
assign o_pf_stall = (master_ce)&&(~pf_v);
assign o_i_count = (alu_pc_v)&&(~clear_pipeline);
 
`ifdef DEBUG_SCOPE
always @(posedge i_clk)
1568,7 → 1617,7
/*
o_break, i_wb_err, pf_pc[1:0],
flags,
pf_valid, dcdvalid, opvalid, alu_valid, mem_valid,
pf_v, dcdvalid, opvalid, alu_v, mem_v,
op_ce, alu_ce, mem_ce,
//
master_ce, opvalid_alu, opvalid_mem,
1584,7 → 1633,7
/*
i_rst, master_ce, (new_pc),
((dcd_early_branch)&&(dcdvalid)),
pf_valid, pf_illegal,
pf_v, pf_illegal,
op_ce, dcd_ce, dcdvalid, dcd_stalled,
pf_cyc, pf_stb, pf_we, pf_ack, pf_stall, pf_err,
pf_pc[7:0], pf_addr[7:0]
1596,12 → 1645,12
(mem_busy)?{ (o_wb_gbl_stb|o_wb_lcl_stb), o_wb_we,
o_wb_addr[8:0] }
: { instruction[31:21] },
pf_valid, (pf_valid) ? alu_pc[14:0]
pf_v, (pf_v) ? alu_pc[14:0]
:{ pf_cyc, pf_stb, pf_pc[12:0] }
 
/*
i_wb_err, gie, new_pc, dcd_early_branch, // 4
pf_valid, pf_cyc, pf_stb, instruction_pc[0], // 4
pf_v, pf_cyc, pf_stb, instruction_pc[0], // 4
instruction[30:27], // 4
dcd_gie, mem_busy, o_wb_gbl_cyc, o_wb_gbl_stb, // 4
dcdvalid,
/openarty/trunk/rtl/toplevel.v
7,8 → 7,9
// Purpose: This is the top level Verilog file. It is to be contrasted
// with the other top level Verilog file in this same project in
// that *this* top level is designed to create a *safe*, low-speed
// (100MHz), configuration that can be used to test peripherals and other
// things on the way to building a full featured high speed configuration.
// (80MHz), configuration that can be used to test peripherals and other
// things on the way to building a full featured high speed (160MHz)
// configuration.
//
// Differences between this file and fasttop.v should be limited to speed
// related differences (such as the number of counts per UART baud), and
44,7 → 45,7
////////////////////////////////////////////////////////////////////////////////
//
//
module toplevel(i_clk_100mhz, i_reset_btn,
module toplevel(sys_clk_i, i_reset_btn,
i_sw, // Switches
i_btn, // Buttons
o_led, // Single color LEDs
56,11 → 57,11
// Missing: Ethernet
o_eth_mdclk, io_eth_mdio,
// Memory
o_ddr_reset_n, o_ddr_cke, o_ddr_ck_p, o_ddr_ck_n,
o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
io_ddr_dqs_p, io_ddr_dqs_n,
o_ddr_addr, o_ddr_ba,
io_ddr_data, o_ddr_dm, o_ddr_odt,
ddr3_reset_n, ddr3_cke, ddr3_ck_p, ddr3_ck_n,
ddr3_cs_n, ddr3_ras_n, ddr3_cas_n, ddr3_we_n,
ddr3_dqs_p, ddr3_dqs_n,
ddr3_addr, ddr3_ba,
ddr3_dq, ddr3_dm, ddr3_odt,
// SD Card
o_sd_sck, io_sd_cmd, io_sd, i_sd_cs, i_sd_wp,
// GPS Pmod
71,7 → 72,8
// PMod I/O
i_aux_rx, i_aux_rts, o_aux_tx, o_aux_cts
);
input i_clk_100mhz, i_reset_btn;
input [0:0] sys_clk_i;
input i_reset_btn;
input [3:0] i_sw; // Switches
input [3:0] i_btn; // Buttons
output wire [3:0] o_led; // LED
87,17 → 89,18
output wire o_eth_mdclk;
inout wire io_eth_mdio;
// DDR3 SDRAM
output wire o_ddr_reset_n;
output wire o_ddr_cke;
output wire o_ddr_ck_p, o_ddr_ck_n;
output wire o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n;
inout [1:0] io_ddr_dqs_p, io_ddr_dqs_n;
output wire [13:0] o_ddr_addr;
output wire [2:0] o_ddr_ba;
inout [15:0] io_ddr_data;
output wire ddr3_reset_n;
output wire [0:0] ddr3_cke;
output wire [0:0] ddr3_ck_p, ddr3_ck_n;
output wire [0:0] ddr3_cs_n;
output wire ddr3_ras_n, ddr3_cas_n, ddr3_we_n;
output wire [2:0] ddr3_ba;
output wire [13:0] ddr3_addr;
output wire [0:0] ddr3_odt;
output wire [1:0] ddr3_dm;
inout [1:0] ddr3_dqs_p, ddr3_dqs_n;
inout [15:0] ddr3_dq;
//
output wire [1:0] o_ddr_dm;
output wire o_ddr_odt;
// SD Card
output wire o_sd_sck;
inout io_sd_cmd;
116,20 → 119,21
output wire o_aux_tx, o_aux_cts;
 
// Build our master clock
wire i_clk, clk_for_ddr, clk2_unused, enet_clk, clk5_unused,
clk_feedback, clk_locked;
wire s_clk, sys_clk, mem_clk_200mhz,
clk1_unused, clk2_unused, enet_clk, clk4_unnused,
clk5_unused, clk_feedback, clk_locked, mem_clk_200mhz_nobuf;
PLLE2_BASE #(
.BANDWIDTH("OPTIMIZED"), // OPTIMIZED, HIGH, LOW
.CLKFBOUT_PHASE(0.0), // Phase offset in degrees of CLKFB, (-360-360)
.CLKIN1_PERIOD(10.0), // Input clock period in ns to ps resolution
.CLKIN1_PERIOD(10.0), // Input clock period in ns resolution
// CLKOUT0_DIVIDE - CLKOUT5_DIVIDE: divide amount for each CLKOUT(1-128)
.CLKFBOUT_MULT(8), // Multiply value for all CLKOUT (2-64)
.CLKOUT0_DIVIDE(8), // 100 MHz (Main clock)
.CLKOUT1_DIVIDE(8), // 100 MHz (DDR3 SDRAM clock)
.CLKOUT2_DIVIDE(16), // 50 MHz (Flash clock, should we need it)
.CLKOUT3_DIVIDE(32), // 25 MHz (Ethernet clock ?)
.CLKOUT4_DIVIDE(16), // 50 MHz (Unused clock?)
.CLKOUT5_DIVIDE(24),
.CLKOUT0_DIVIDE(8), // 100 MHz (Clock for MIG)
.CLKOUT1_DIVIDE(4), // 200 MHz (MIG Reference clock)
.CLKOUT2_DIVIDE(32), // 50 MHz (Unused)
.CLKOUT3_DIVIDE(64), // 25 MHz (Unused/Ethernet clock)
.CLKOUT4_DIVIDE(32), // 50 MHz (Unused clock?)
.CLKOUT5_DIVIDE(24), // 66 MHz
// CLKOUT0_DUTY_CYCLE -- Duty cycle for each CLKOUT
.CLKOUT0_DUTY_CYCLE(0.5),
.CLKOUT1_DUTY_CYCLE(0.5),
139,58 → 143,101
.CLKOUT5_DUTY_CYCLE(0.5),
// CLKOUT0_PHASE -- phase offset for each CLKOUT
.CLKOUT0_PHASE(0.0),
.CLKOUT1_PHASE(90.0),
.CLKOUT1_PHASE(0.0),
.CLKOUT2_PHASE(0.0),
.CLKOUT3_PHASE(0.0),
.CLKOUT4_PHASE(0.0),
.CLKOUT5_PHASE(0.0),
.DIVCLK_DIVIDE(1), // Master division value , (1-56)
.REF_JITTER1(0.0), // Reference input jitter in UI (0.000-0.999)
.STARTUP_WAIT("FALSE") // Delayu DONE until PLL Locks, ("TRUE"/"FALSE")
.REF_JITTER1(0.0), // Ref. input jitter in UI (0.000-0.999)
.STARTUP_WAIT("TRUE") // Delay DONE until PLL Locks, ("TRUE"/"FALSE")
) genclock(
// Clock outputs: 1-bit (each) output
.CLKOUT0(i_clk),
.CLKOUT1(clk_for_ddr),
.CLKOUT2(clk2_unused), // Reserved for flash, should we need it
.CLKOUT0(mem_clk_nobuf),
.CLKOUT1(mem_clk_200mhz_nobuf),
.CLKOUT2(clk2_unused),
.CLKOUT3(enet_clk),
.CLKOUT4(clk4_unused),
.CLKOUT5(clk5_unused),
.CLKFBOUT(clk_feedback), // 1-bit output, feedback clock
.LOCKED(clk_locked),
.CLKIN1(i_clk_100mhz),
.CLKIN1(sys_clk),
.PWRDWN(1'b0),
.RST(1'b0),
.CLKFBIN(clk_feedback) // 1-bit input, feedback clock
.CLKFBIN(clk_feedback_bufd) // 1-bit input, feedback clock
);
 
BUFH feedback_buffer(.I(clk_feedback),.O(clk_feedback_bufd));
// BUFG memref_buffer(.I(mem_clk_200mhz_nobuf),.O(mem_clk_200mhz));
IBUF sysclk_buf(.I(sys_clk_i[0]), .O(sys_clk));
 
//
//
// UART interface
//
//
wire [29:0] bus_uart_setup;
assign bus_uart_setup = 30'h10000019; // 4MBaud, 7 bits
// assign bus_uart_setup = 30'h10000014; // ~4MBaud, 7 bits
assign bus_uart_setup = 30'h10000051; // ~1MBaud, 7 bits
 
wire [7:0] rx_data, tx_data;
wire rx_break, rx_parity_err, rx_frame_err, rx_stb;
wire tx_stb, tx_busy;
 
reg pwr_reset, pre_reset;
initial pwr_reset = 1'b1;
//
// RESET LOGIC
//
// Okay, so this looks bad at a first read--but it's not really that
// bad. If you look close, there are two parts to the reset logic.
// The first is the "PRE"-reset. This is a wire, set from the external
// reset button. In good old-fashioned asynch-logic to synchronous
// logic fashion, we synchronize this wire by registering it first
// to pre_reset, and then to pwr_reset (the actual reset wire).
//
reg [7:0] pre_reset;
reg pwr_reset;
// Since all our stuff is synchronous to the clock that comes out of
// the memory controller, sys_reset must needs come out of the memory
// controller.
//
// Logic description starts with the PRE-reset, so as to make certain
// we include the reset button. The memory controller wants an active
// low reset here, so we provide such.
initial pre_reset = 1'b0;
always @(posedge i_clk)
pre_reset <= ~i_reset_btn;
always @(posedge i_clk)
pwr_reset <= pre_reset;
always @(posedge sys_clk)
pre_reset <= ((!i_reset_btn)||(!clk_locked))
? 8'h00 : {pre_reset[6:0], 1'b1};
//
// and then continues with the actual reset, now that we've
// synchronized our reset button wire. This is an active LOW reset.
initial pwr_reset = 1'b0;
always @(posedge sys_clk)
pwr_reset <= pre_reset[7];
//
// Of course, this only goes into the memory controller. The true
// device reset comes out of that memory controller, synchronized to
// our memory generator provided clock(s)
 
wire w_ck_uart, w_uart_tx;
rxuart rcv(i_clk, pwr_reset, bus_uart_setup, i_uart_rx,
rxuart rcv(s_clk, s_reset, bus_uart_setup, i_uart_rx,
rx_stb, rx_data, rx_break,
rx_parity_err, rx_frame_err, w_ck_uart);
txuart txv(i_clk, pwr_reset, bus_uart_setup, 1'b0,
txuart txv(s_clk, s_reset, bus_uart_setup|30'h8000000, 1'b0,
tx_stb, tx_data, o_uart_tx, tx_busy);
 
 
wire [3:0] w_led;
reg [24:0] dbg_counter;
always @(posedge sys_clk)
dbg_counter <= dbg_counter + 25'h01;
assign o_led = { w_led[3:2],
((!pwr_reset)&(dbg_counter[24]))
||((pwr_reset)&&(w_led[1])),
(s_reset & dbg_counter[23])
||((!s_reset)&&(w_led[0])) };
 
 
 
 
//////
//
//
197,37 → 244,46
// The WB bus interconnect, herein called busmaster, which handles
// just about ... everything. It is in contrast to the other WB bus
// interconnect, fastmaster, in that the busmaster build permits
// peripherals that can *only* operate at 100MHz, no faster.
// peripherals that can *only* operate at 80MHz, no faster, no slower.
//
//
//////
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;
 
//
wire [2:0] w_ddr_dqs;
wire [31:0] wo_ddr_data, wi_ddr_data;
// The SDRAM interface wires
//
wire ram_cyc, ram_stb, ram_we;
wire [25:0] ram_addr;
wire [31:0] ram_rdata, ram_wdata;
wire ram_ack, ram_stall, ram_err;
wire [31:0] ram_dbg;
//
wire w_mdio, w_mdwe;
//
wire w_sd_cmd;
wire [3:0] w_sd_data;
busmaster wbbus(i_clk, pwr_reset,
busmaster wbbus(s_clk, s_reset,
// External USB-UART bus control
rx_stb, rx_data, tx_stb, tx_data, tx_busy,
// Board lights and switches
i_sw, i_btn, o_led,
i_sw, i_btn, w_led,
o_clr_led0, o_clr_led1, o_clr_led2, o_clr_led3,
// 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,
o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
w_ddr_dqs, o_ddr_addr, o_ddr_ba, wo_ddr_data, wi_ddr_data,
// o_ddr_reset_n, o_ddr_cke, o_ddr_ck_p, o_ddr_ck_n,
// o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
// o_ddr_ba, o_ddr_addr, o_ddr_odt, o_ddr_dm,
// io_ddr_dqs_p, io_ddr_dqs_n, io_ddr_data,
ram_cyc, ram_stb, ram_we, ram_addr, ram_wdata,
ram_ack, ram_stall, ram_rdata, ram_err,
ram_dbg,
// SD Card
o_sd_sck, w_sd_cmd, w_sd_data, io_sd_cmd, io_sd, i_sd_cs,
// Ethernet control (MDIO) lines
264,32 → 320,25
// ?? Dual mode out (not yet)
//
//
// assign io_qspi_dat = (~qspi_bmod[1])?({2'b11,1'bz,qspi_dat[0]})
// :((qspi_bmod[0])?(4'bzzzz):(qspi_dat[3:0]));
// assign i_qspi_dat = io_qspi_dat;
//
wire [3:0] i_qspi_dat_ign;
ODDR #(.DDR_CLK_EDGE("OPPOSITE_EDGE"), .INIT(1'b1), .SRTYPE("SYNC"))
qsck(
.Q(o_qspi_sck),
.C(i_clk),
.CE(1'b1),
.D1(w_qspi_sck),
.D2(w_qspi_sck),
.R(1'b0), .S(1'b0));
xioddr qd0(i_clk, (~qspi_bmod[1])|(~qspi_bmod[0]),
wire [3:0] i_qspi_pedge, i_qspi_nedge;
 
xoddr xqspi_sck( s_clk, { w_qspi_sck, w_qspi_sck }, o_qspi_sck);
xoddr xqspi_csn( s_clk, { w_qspi_cs_n, w_qspi_cs_n },o_qspi_cs_n);
//
xioddr xqspi_d0( s_clk, (qspi_bmod != 2'b11),
{ qspi_dat[0], qspi_dat[0] },
{ i_qspi_dat_ign[0], i_qspi_dat[0] }, io_qspi_dat[0]);
xioddr qd1(i_clk, (qspi_bmod == 2'b10),
{ i_qspi_pedge[0], i_qspi_nedge[0] }, io_qspi_dat[0]);
xioddr xqspi_d1( s_clk, (qspi_bmod==2'b10),
{ qspi_dat[1], qspi_dat[1] },
{ i_qspi_dat_ign[1], i_qspi_dat[1] }, io_qspi_dat[1]);
xioddr qd2(i_clk, (~qspi_bmod[1])||(~qspi_bmod[0]),
{ qspi_dat[2], qspi_dat[2] },
{ i_qspi_dat_ign[2], i_qspi_dat[2] }, io_qspi_dat[2]);
xioddr qd3(i_clk, (~qspi_bmod[1])||(~qspi_bmod[0]),
{ qspi_dat[3], qspi_dat[3] },
{ i_qspi_dat_ign[3], i_qspi_dat[3] }, io_qspi_dat[3]);
{ i_qspi_pedge[1], i_qspi_nedge[1] }, io_qspi_dat[1]);
xioddr xqspi_d2( s_clk, (qspi_bmod!=2'b11),
(qspi_bmod[1])?{ qspi_dat[2], qspi_dat[2] }:2'b11,
{ i_qspi_pedge[2], i_qspi_nedge[2] }, io_qspi_dat[2]);
xioddr xqspi_d3( s_clk, (qspi_bmod!=2'b11),
(qspi_bmod[1])?{ qspi_dat[3], qspi_dat[3] }:2'b11,
{ i_qspi_pedge[3], i_qspi_nedge[3] }, io_qspi_dat[3]);
 
assign i_qspi_dat = i_qspi_pedge;
//
// Proposed QSPI mode select, to allow dual I/O mode
// 000 Normal SPI mode
299,74 → 348,8
// 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 in order to gain access
// to the o_qspi_sck pin.
//
//
/*
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
377,7 → 360,6
assign io_sd[1] = w_sd_data[1]? 1'bz:1'b0;
assign io_sd[2] = w_sd_data[2]? 1'bz:1'b0;
assign io_sd[3] = w_sd_data[3]? 1'bz:1'b0;
assign o_sd_wp = 1'b0;
 
 
//
387,73 → 369,31
//
assign io_eth_mdio = (w_mdwe)?w_mdio : 1'bz;
 
 
//
//
// Wires for setting up the DDR3 memory
// Now, to set up our memory ...
//
//
wire [31:0] r_ddr_data;
migsdram rami(
.i_clk(mem_clk_nobuf), .i_clk_200mhz(mem_clk_200mhz_nobuf),
.o_sys_clk(s_clk), .i_rst(pwr_reset), .o_sys_reset(s_reset),
.i_wb_cyc(ram_cyc), .i_wb_stb(ram_stb), .i_wb_we(ram_we),
.i_wb_addr(ram_addr), .i_wb_data(ram_wdata),
.i_wb_sel(4'hf),
.o_wb_ack(ram_ack), .o_wb_stall(ram_stall),
.o_wb_data(ram_rdata), .o_wb_err(ram_err),
.o_ddr_ck_p(ddr3_ck_p), .o_ddr_ck_n(ddr3_ck_n),
.o_ddr_reset_n(ddr3_reset_n), .o_ddr_cke(ddr3_cke),
.o_ddr_cs_n(ddr3_cs_n), .o_ddr_ras_n(ddr3_ras_n),
.o_ddr_cas_n(ddr3_cas_n), .o_ddr_we_n(ddr3_we_n),
.o_ddr_ba(ddr3_ba), .o_ddr_addr(ddr3_addr),
.o_ddr_odt(ddr3_odt), .o_ddr_dm(ddr3_dm),
.io_ddr_dqs_p(ddr3_dqs_p), .io_ddr_dqs_n(ddr3_dqs_n),
.io_ddr_data(ddr3_dq),
//
.o_ram_dbg(ram_dbg)
);
 
xioddr p0(i_clk, ~o_ddr_we_n, { wo_ddr_data[16], wo_ddr_data[0] },
{ wi_ddr_data[16], wi_ddr_data[0] }, io_ddr_data[0]);
 
xioddr p1(i_clk, ~o_ddr_we_n, { wo_ddr_data[17], wo_ddr_data[1] },
{ wi_ddr_data[17], wi_ddr_data[1] }, io_ddr_data[1]);
 
xioddr p2(i_clk, ~o_ddr_we_n, { wo_ddr_data[18], wo_ddr_data[2] },
{ wi_ddr_data[18], wi_ddr_data[2] }, io_ddr_data[2]);
 
xioddr p3(i_clk, ~o_ddr_we_n, { wo_ddr_data[19], wo_ddr_data[3] },
{ wi_ddr_data[19], wi_ddr_data[3] }, io_ddr_data[3]);
 
xioddr p4(i_clk, ~o_ddr_we_n, { wo_ddr_data[20], wo_ddr_data[4] },
{ wi_ddr_data[20], wi_ddr_data[4] }, io_ddr_data[4]);
 
xioddr p5(i_clk, ~o_ddr_we_n, { wo_ddr_data[21], wo_ddr_data[5] },
{ wi_ddr_data[21], wi_ddr_data[5] }, io_ddr_data[5]);
 
xioddr p6(i_clk, ~o_ddr_we_n, { wo_ddr_data[22], wo_ddr_data[6] },
{ wi_ddr_data[22], wi_ddr_data[6] }, io_ddr_data[6]);
 
xioddr p7(i_clk, ~o_ddr_we_n, { wo_ddr_data[23], wo_ddr_data[7] },
{ wi_ddr_data[23], wi_ddr_data[7] }, io_ddr_data[7]);
 
xioddr p8(i_clk, ~o_ddr_we_n, { wo_ddr_data[24], wo_ddr_data[8] },
{ wi_ddr_data[24], wi_ddr_data[8] }, io_ddr_data[8]);
 
xioddr p9(i_clk, ~o_ddr_we_n, { wo_ddr_data[25], wo_ddr_data[9] },
{ wi_ddr_data[25], wi_ddr_data[9] }, io_ddr_data[9]);
 
xioddr pa(i_clk, ~o_ddr_we_n, { wo_ddr_data[26], wo_ddr_data[10] },
{ wi_ddr_data[26], wi_ddr_data[10] }, io_ddr_data[10]);
 
xioddr pb(i_clk, ~o_ddr_we_n, { wo_ddr_data[27], wo_ddr_data[11] },
{ wi_ddr_data[27], wi_ddr_data[11] }, io_ddr_data[11]);
 
xioddr pc(i_clk, ~o_ddr_we_n, { wo_ddr_data[28], wo_ddr_data[12] },
{ wi_ddr_data[28], wi_ddr_data[12] }, io_ddr_data[12]);
 
xioddr pd(i_clk, ~o_ddr_we_n, { wo_ddr_data[29], wo_ddr_data[13] },
{ wi_ddr_data[29], wi_ddr_data[13] }, io_ddr_data[13]);
 
xioddr pe(i_clk, ~o_ddr_we_n, { wo_ddr_data[30], wo_ddr_data[14] },
{ wi_ddr_data[30], wi_ddr_data[14] }, io_ddr_data[14]);
 
xioddr pf(i_clk, ~o_ddr_we_n, { wo_ddr_data[31], wo_ddr_data[15] },
{ wi_ddr_data[31], wi_ddr_data[15] }, io_ddr_data[15]);
 
OBUFTDS #(.IOSTANDARD("DIFF_SSTL135"), .SLEW("FAST"))
dqsbuf0(.O(io_ddr_dqs_p[0]), .OB(io_ddr_dqs_n[0]),
.I(w_ddr_dqs[1]), .T(w_ddr_dqs[2]));
OBUFTDS #(.IOSTANDARD("DIFF_SSTL135"), .SLEW("FAST"))
dqsbuf1(.O(io_ddr_dqs_p[1]), .OB(io_ddr_dqs_n[1]),
.I(w_ddr_dqs[0]), .T(w_ddr_dqs[2]));
 
OBUFDS #(.IOSTANDARD("DIFF_SSTL135"), .SLEW("FAST"))
clkbuf(.O(o_ddr_ck_p), .OB(o_ddr_ck_n), .I(clk_for_ddr));
 
assign o_ddr_dm = 2'b00;
assign o_ddr_odt = 1'b0;
 
endmodule
 
/openarty/trunk/rtl/gpsclock_tb.v
70,7 → 70,7
if ((i_wb_cyc_stb)&&(i_wb_we))
begin
case(i_wb_addr)
3'b000: r_maxcount <= i_wb_data;
3'b000: r_maxcount <= i_wb_data;
3'b001: r_jump <= i_wb_data;
// 2'b11: r_def_step <= i_wb_data;
default: begin end
94,7 → 94,7
3'b101: o_wb_data <= r_count[31:0];
3'b110: o_wb_data <= r_step[63:32];
3'b111: begin o_wb_data <= r_step[31:0]; r_halt <= 1'b0; end
default: o_wb_data <= 0;
// default: o_wb_data <= 0;
endcase
 
always @(posedge i_clk)
/openarty/trunk/rtl/rtcgps.v
54,10 → 54,12
// Our personal timing, for debug purposes
o_rtc_pps);
parameter DEFAULT_SPEED = 32'd2814750; //2af31e = 2^48 / 100e6 MHz
input i_clk;
input i_wb_cyc, i_wb_stb, i_wb_we;
input [1:0] i_wb_addr;
input [31:0] i_wb_data;
//
input i_clk;
//
input i_wb_cyc, i_wb_stb, i_wb_we;
input [1:0] i_wb_addr;
input [31:0] i_wb_data;
// input i_btn;
output reg [31:0] o_data;
output wire o_interrupt, o_ppd;
/openarty/trunk/rtl/migsdram.v
0,0 → 1,307
////////////////////////////////////////////////////////////////////////////////
//
// Filename: migsdram.v
//
// Project: OpenArty, an entirely open SoC based upon the Arty platform
//
// Purpose: To interface the Arty to a MIG Generated SDRAM
//
// 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 migsdram(i_clk, i_clk_200mhz, o_sys_clk, i_rst, o_sys_reset,
// Wishbone components
i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, i_wb_sel,
o_wb_ack, o_wb_stall, o_wb_data, o_wb_err,
// SDRAM connections
o_ddr_ck_p, o_ddr_ck_n,
o_ddr_reset_n, o_ddr_cke,
o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
o_ddr_ba, o_ddr_addr,
o_ddr_odt, o_ddr_dm,
io_ddr_dqs_p, io_ddr_dqs_n,
io_ddr_data,
// Debug connection
o_ram_dbg
);
parameter DDRWIDTH = 16, WBDATAWIDTH=32;
parameter AXIDWIDTH = 6;
// The SDRAM address bits (RAMABITS) are a touch more difficult to work
// out. Here we leave them as a fixed parameter, but there are
// consequences to this. Specifically, the wishbone data width, the
// wishbone address width, and this number have interactions not
// well captured here.
parameter RAMABITS = 28;
// All DDR3 memories have 8 timeslots. This, if the DDR3 memory
// has 16 bits to it (as above), the entire transaction must take
// AXIWIDTH bits ...
localparam AXIWIDTH= DDRWIDTH *8;
localparam DW=WBDATAWIDTH;
localparam AW=(WBDATAWIDTH==32)? RAMABITS-2
:((WBDATAWIDTH==64) ? RAMABITS-3
:((WBDATAWIDTH==128) ? RAMABITS-4
: RAMABITS-5)); // (WBDATAWIDTH==256)
localparam SELW= (WBDATAWIDTH/8);
//
input i_clk, i_clk_200mhz, i_rst;
output o_sys_clk;
output reg o_sys_reset;
//
input i_wb_cyc, i_wb_stb, i_wb_we;
input [(AW-1):0] i_wb_addr;
input [(DW-1):0] i_wb_data;
input [(SELW-1):0] i_wb_sel;
output wire o_wb_ack, o_wb_stall;
output wire [(DW-1):0] o_wb_data;
output wire o_wb_err;
//
output wire [0:0] o_ddr_ck_p, o_ddr_ck_n;
output wire [0:0] o_ddr_cke;
output wire o_ddr_reset_n,
o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n;
output wire [0:0] o_ddr_cs_n;
output wire [2:0] o_ddr_ba;
output wire [13:0] o_ddr_addr;
output wire [0:0] o_ddr_odt;
output wire [(DDRWIDTH/8-1):0] o_ddr_dm;
inout wire [1:0] io_ddr_dqs_p, io_ddr_dqs_n;
inout wire [(DDRWIDTH-1):0] io_ddr_data;
 
output wire [31:0] o_ram_dbg;
 
 
`define SDRAM_ACCESS
`ifdef SDRAM_ACCESS
 
wire aresetn;
assign aresetn = 1'b1; // Never reset
 
// Write address channel
wire [(AXIDWIDTH-1):0] s_axi_awid;
wire [(RAMABITS-1):0] s_axi_awaddr;
wire [7:0] s_axi_awlen;
wire [2:0] s_axi_awsize;
wire [1:0] s_axi_awburst;
wire [0:0] s_axi_awlock;
wire [3:0] s_axi_awcache;
wire [2:0] s_axi_awprot;
wire [3:0] s_axi_awqos;
wire s_axi_awvalid;
wire s_axi_awready;
// Writei data channel
wire [(AXIWIDTH-1):0] s_axi_wdata;
wire [(AXIWIDTH/8-1):0] s_axi_wstrb;
wire s_axi_wlast, s_axi_wvalid, s_axi_wready;
// Write response channel
wire s_axi_bready;
wire [(AXIDWIDTH-1):0] s_axi_bid;
wire [1:0] s_axi_bresp;
wire s_axi_bvalid;
 
// Read address channel
wire [(AXIDWIDTH-1):0] s_axi_arid;
wire [(RAMABITS-1):0] s_axi_araddr;
wire [7:0] s_axi_arlen;
wire [2:0] s_axi_arsize;
wire [1:0] s_axi_arburst;
wire [0:0] s_axi_arlock;
wire [3:0] s_axi_arcache;
wire [2:0] s_axi_arprot;
wire [3:0] s_axi_arqos;
wire s_axi_arvalid;
// Read response/data channel
wire [(AXIDWIDTH-1):0] s_axi_rid;
wire [(AXIWIDTH-1):0] s_axi_rdata;
wire [1:0] s_axi_rresp;
wire s_axi_rlast;
wire s_axi_rvalid;
 
// Other wires ...
wire init_calib_complete, mmcm_locked;
wire app_sr_active, app_ref_ack, app_zq_ack;
wire app_sr_req, app_ref_req, app_zq_req;
wire w_sys_reset;
wire [11:0] w_device_temp;
 
 
mig_axis mig_sdram(
.ddr3_ck_p(o_ddr_ck_p), .ddr3_ck_n(o_ddr_ck_n),
.ddr3_reset_n(o_ddr_reset_n), .ddr3_cke(o_ddr_cke),
.ddr3_cs_n(o_ddr_cs_n), .ddr3_ras_n(o_ddr_ras_n),
.ddr3_we_n(o_ddr_we_n), .ddr3_cas_n(o_ddr_cas_n),
.ddr3_ba(o_ddr_ba), .ddr3_addr(o_ddr_addr),
.ddr3_odt(o_ddr_odt),
.ddr3_dqs_p(io_ddr_dqs_p), .ddr3_dqs_n(io_ddr_dqs_n),
.ddr3_dq(io_ddr_data), .ddr3_dm(o_ddr_dm),
//
.sys_clk_i(i_clk),
.clk_ref_i(i_clk_200mhz),
.ui_clk(o_sys_clk),
.ui_clk_sync_rst(w_sys_reset),
.mmcm_locked(mmcm_locked),
.aresetn(aresetn),
.app_sr_req(1'b0),
.app_ref_req(1'b0),
.app_zq_req(1'b0),
.app_sr_active(app_sr_active),
.app_ref_ack(app_ref_ack),
.app_zq_ack(app_zq_ack),
//
.s_axi_awid(s_axi_awid), .s_axi_awaddr(s_axi_awaddr),
.s_axi_awlen(s_axi_awlen), .s_axi_awsize(s_axi_awsize),
.s_axi_awburst(s_axi_awburst), .s_axi_awlock(s_axi_awlock),
.s_axi_awcache(s_axi_awcache), .s_axi_awprot(s_axi_awprot),
.s_axi_awqos(s_axi_awqos), .s_axi_awvalid(s_axi_awvalid),
.s_axi_awready(s_axi_awready),
//
.s_axi_wready( s_axi_wready),
.s_axi_wdata( s_axi_wdata),
.s_axi_wstrb( s_axi_wstrb),
.s_axi_wlast( s_axi_wlast),
.s_axi_wvalid( s_axi_wvalid),
//
.s_axi_bready(s_axi_bready), .s_axi_bid(s_axi_bid),
.s_axi_bresp(s_axi_bresp), .s_axi_bvalid(s_axi_bvalid),
//
.s_axi_arid(s_axi_arid), .s_axi_araddr(s_axi_araddr),
.s_axi_arlen(s_axi_arlen), .s_axi_arsize(s_axi_arsize),
.s_axi_arburst(s_axi_arburst), .s_axi_arlock(s_axi_arlock),
.s_axi_arcache(s_axi_arcache), .s_axi_arprot(s_axi_arprot),
.s_axi_arqos(s_axi_arqos), .s_axi_arvalid(s_axi_arvalid),
.s_axi_arready(s_axi_arready),
//
.s_axi_rready(s_axi_rready), .s_axi_rid(s_axi_rid),
.s_axi_rdata(s_axi_rdata), .s_axi_rresp(s_axi_rresp),
.s_axi_rlast(s_axi_rlast), .s_axi_rvalid(s_axi_rvalid),
.init_calib_complete(init_calib_complete),
.sys_rst(i_rst),
.device_temp(w_device_temp)
);
 
wbm2axisp #(
.C_AXI_ID_WIDTH(AXIDWIDTH),
.C_AXI_DATA_WIDTH(AXIWIDTH),
.C_AXI_ADDR_WIDTH(RAMABITS),
.AW(AW), .DW(DW)
)
bus_translator (
.i_clk(o_sys_clk),
// .i_reset(i_rst), // internally unused
// Write address channel signals
.o_axi_awid( s_axi_awid),
.o_axi_awaddr( s_axi_awaddr),
.o_axi_awlen( s_axi_awlen),
.o_axi_awsize( s_axi_awsize),
.o_axi_awburst( s_axi_awburst),
.o_axi_awlock( s_axi_awlock),
.o_axi_awcache( s_axi_awcache),
.o_axi_awprot( s_axi_awprot), // s_axi_awqos
.o_axi_awqos( s_axi_awqos), // s_axi_awqos
.o_axi_awvalid( s_axi_awvalid),
.i_axi_awready( s_axi_awready),
//
.i_axi_wready( s_axi_wready),
.o_axi_wdata( s_axi_wdata),
.o_axi_wstrb( s_axi_wstrb),
.o_axi_wlast( s_axi_wlast),
.o_axi_wvalid( s_axi_wvalid),
//
.o_axi_bready( s_axi_bready),
.i_axi_bid( s_axi_bid),
.i_axi_bresp( s_axi_bresp),
.i_axi_bvalid( s_axi_bvalid),
//
.i_axi_arready( s_axi_arready),
.o_axi_arid( s_axi_arid),
.o_axi_araddr( s_axi_araddr),
.o_axi_arlen( s_axi_arlen),
.o_axi_arsize( s_axi_arsize),
.o_axi_arburst( s_axi_arburst),
.o_axi_arlock( s_axi_arlock),
.o_axi_arcache( s_axi_arcache),
.o_axi_arprot( s_axi_arprot),
.o_axi_arqos( s_axi_arqos),
.o_axi_arvalid( s_axi_arvalid),
//
.o_axi_rready( s_axi_rready),
.i_axi_rid( s_axi_rid),
.i_axi_rdata( s_axi_rdata),
.i_axi_rresp( s_axi_rresp),
.i_axi_rlast( s_axi_rlast),
.i_axi_rvalid( s_axi_rvalid),
//
.i_wb_cyc( i_wb_cyc),
.i_wb_stb( i_wb_stb),
.i_wb_we( i_wb_we),
.i_wb_addr( i_wb_addr),
.i_wb_data( i_wb_data),
.i_wb_sel( i_wb_sel),
//
.o_wb_ack( o_wb_ack),
.o_wb_stall( o_wb_stall),
.o_wb_data( o_wb_data),
.o_wb_err( o_wb_err),
//
.o_dbg( o_ram_dbg)
);
 
// Convert from active low to active high, *and* hold the system in
// reset until the memory comes up.
initial o_sys_reset = 1'b1;
always @(posedge o_sys_clk)
o_sys_reset <= (w_sys_reset)
||(!init_calib_complete)
||(!mmcm_locked);
`else
BUFG sysclk(i_clk, o_sys_clk);
initial o_sys_reset <= 1'b1;
always @(posedge i_clk)
o_sys_reset <= 1'b1;
 
OBUFDS ckobuf(.I(i_clk), .O(o_ddr_ck_p), .OB(o_ddr_ck_n));
 
assign o_ddr_reset_n = 1'b0;
assign o_ddr_cke[0] = 1'b0;
assign o_ddr_cs_n[0] = 1'b1;
assign o_ddr_cas_n = 1'b1;
assign o_ddr_ras_n = 1'b1;
assign o_ddr_we_n = 1'b1;
assign o_ddr_ba = 3'h0;
assign o_ddr_addr = 14'h00;
assign o_ddr_dm = 2'b00;
assign io_ddr_data = 16'h0;
 
OBUFDS dqsbufa(.I(i_clk), .O(io_ddr_dqs_p[1]), .OB(io_ddr_dqs_n[1]));
OBUFDS dqsbufb(.I(i_clk), .O(io_ddr_dqs_p[0]), .OB(io_ddr_dqs_n[0]));
 
`endif
 
endmodule
 
 
/openarty/trunk/rtl/gpsclock.v
102,6 → 102,7
i_wb_cyc_stb, i_wb_we, i_wb_addr, i_wb_data,
o_wb_ack, o_wb_stall, o_wb_data,
o_tracking, o_count, o_step, o_err, o_locked, o_dbg);
parameter DEFAULT_STEP = 32'h834d_c736;//2^64/81.25 MHz
parameter RW=64, // Needs to be 2ceil(Log_2(i_clk frequency))
DW=32, // The width of our data bus
ONE_SECOND = 0,
177,8 → 178,9
//
//
//
// DEFAULT_STEP = 64'h0000_002a_f31d_c461, // 2^64 / 100 MHz
initial r_def_step = 32'h8_2af_31dc;
// DEFAULT_STEP = 64'h0000_0034_dc73_67da, // 2^64 / 100 MHz
// 28'h34d_c736 << 8, and hence we have 32'h834d_c736
initial r_def_step = DEFAULT_STEP;
always @(posedge i_clk)
pre_step <= { 16'h00,
(({ r_def_step[27:0], 20'h00 })>>r_def_step[31:28])};
208,7 → 210,7
2'b01: r_beta <= wb_data;
2'b10: r_gamma <= wb_data;
2'b11: r_def_step <= wb_data;
default: begin end
// default: begin end
// r_defstep <= i_wb_data;
endcase
end else
219,7 → 221,7
2'b01: o_wb_data <= r_beta;
2'b10: o_wb_data <= r_gamma;
2'b11: o_wb_data <= r_def_step;
default: o_wb_data <= 0;
// default: o_wb_data <= 0;
endcase
 
reg dly_config;
/openarty/trunk/rtl/Makefile
42,8 → 42,8
.PHONY: test
test: $(VDIRFB)/Veqspiflash__ALL.a
test: $(VDIRFB)/Venetctrl__ALL.a
test: $(VDIRFB)/Vfastmaster__ALL.a
# test: $(VDIRFB)/Vfastmaster__ALL.a
test: $(VDIRFB)/Vbusmaster__ALL.a
 
CPUDR := cpu
CPUSOURCESnD := zipcpu.v fastops.v pfcache.v pipemem.v \
56,7 → 56,7
wbucompress.v wbudecompress.v wbudeword.v wbuexec.v \
wbuidleint.v wbuinput.v wbuoutput.v wbureadcw.v wbusixchar.v \
wbutohex.v
PERIPHERALS:= enetctrl.v fastio.v icontrol.v rtcdate.v rtcgps.v \
PERIPHERALS:= enetctrl.v fastio.v rtcdate.v rtcgps.v \
rxuart.v txuart.v eqspiflash.v lleqspi.v flash_config.v \
wbicapetwo.v sdspi.v gpsclock_tb.v gpsclock.v wboled.v lloled.v \
wbscopc.v wbscope.v memdev.v wbddrsdram.v
/openarty/trunk/rtl/bigsmpy.v
36,82 → 36,143
//
//
module bigsmpy(i_clk, i_sync, i_sgn, i_a, i_b, o_r, o_sync);
parameter CLOCKS = 1;
input i_clk, i_sync, i_sgn;
input [31:0] i_a, i_b;
output reg [63:0] o_r;
output reg o_sync;
 
//
// A pipeline, shift register, to track our synchronization pulse
reg [3:0] r_s;
generate
if (CLOCKS == 1)
begin
wire signed [31:0] w_sa, w_sb;
wire [31:0] w_ua, w_ub;
 
//
reg r_mpy_signed;
reg [31:0] r_mpy_a_input, r_mpy_b_input;
always @(posedge i_clk)
assign w_sa = i_a;
assign w_sb = i_b;
assign w_ua = i_a;
assign w_ub = i_b;
 
always @(posedge i_clk)
begin
o_sync <= i_sync;
if (i_sgn)
o_r <= w_sa * w_sb;
else
o_r <= w_ua * w_ub;
end
 
end else if (CLOCKS == 2)
begin
if (i_sgn)
reg signed [31:0] r_sa, r_sb;
wire [31:0] w_ua, w_ub;
 
always @(posedge i_clk)
begin
r_mpy_a_input <= {(~i_a[31]), i_a[30:0] };
r_mpy_b_input <= {(~i_b[31]), i_b[30:0] };
end else begin
r_mpy_a_input <= i_a[31:0];
r_mpy_b_input <= i_b[31:0];
r_sa = i_a;
r_sb = i_b;
end
 
r_mpy_signed <= i_sgn;
r_s[0] <= i_sync;
end
assign w_ua = r_sa;
assign w_ub = r_sb;
 
reg [31:0] pp_f, pp_o, pp_i, pp_l;
reg [32:0] pp_s;
always @(posedge i_clk)
always @(posedge i_clk)
begin
o_sync <= i_sync;
if (i_sgn)
o_r <= r_sa * r_sb;
else
o_r <= w_ua * w_ub;
end
 
end else if (CLOCKS == 5)
begin
pp_f <= r_mpy_a_input[31:16] * r_mpy_b_input[31:16];
pp_o <= r_mpy_a_input[31:16] * r_mpy_b_input[15: 0];
pp_i <= r_mpy_a_input[15: 0] * r_mpy_b_input[31:16];
pp_l <= r_mpy_a_input[15: 0] * r_mpy_b_input[15: 0];
//
// A pipeline, shift register, to track our
// synchronization pulse as it transits our pipeline
//
reg [3:0] r_s;
 
if (r_mpy_signed)
pp_s <= 32'h8000_0000 - (r_mpy_a_input[31:0]
+ r_mpy_b_input[31:0]);
else
pp_s <= 33'h0;
r_s[1] <= r_s[0];
end
//
// Clock #1: Register our inputs, copy the value of the sign
// bit.
reg r_mpy_signed;
reg [31:0] r_mpy_a_input, r_mpy_b_input;
always @(posedge i_clk)
begin
if (i_sgn)
begin
// This is about more than making the inputs
// unsigned, as you'll notice it makes positive
// inputs otherwise negative. Instead,
// this is about making the inputs have offset
// mode. Hence
// i_a = r_mpy_a_input - 2^31
// and so forth
r_mpy_a_input <= {(~i_a[31]), i_a[30:0] };
r_mpy_b_input <= {(~i_b[31]), i_b[30:0] };
end else begin
r_mpy_a_input <= i_a[31:0];
r_mpy_b_input <= i_b[31:0];
end
 
reg [32:0] partial_mpy_oi, partial_mpy_lo;
reg [31:0] partial_mpy_hi;
always @(posedge i_clk)
begin
partial_mpy_lo[30: 0] <= pp_l[30:0];
partial_mpy_lo[32:31] <= pp_s[0] + pp_l[31];
partial_mpy_oi[32: 0] <= pp_o + pp_i;
partial_mpy_hi[31: 0] <= pp_s[32:1] + pp_f;
r_s[2] <= r_s[1];
end
r_mpy_signed <= i_sgn;
r_s[0] <= i_sync;
end
 
reg partial_mpy_2cl, partial_mpy_2ch;
reg [31:0] partial_mpy_2lo, partial_mpy_2hi;
always @(posedge i_clk)
begin
partial_mpy_2lo[15:0] <= partial_mpy_lo[15:0];
{ partial_mpy_2cl, partial_mpy_2lo[31:16] }
<= { 1'b0, partial_mpy_oi[15:0]}+ partial_mpy_lo[32:16];
{ partial_mpy_2ch, partial_mpy_2hi[16:0] }
<= partial_mpy_oi[32:16] + partial_mpy_hi[16:0];
partial_mpy_2hi[31:16] <= { partial_mpy_2hi[31:17], 1'b0 };
r_s[3] <= r_s[2];
end
reg [31:0] pp_f, pp_o, pp_i, pp_l;
reg [32:0] pp_s;
always @(posedge i_clk)
begin
pp_f <= r_mpy_a_input[31:16] * r_mpy_b_input[31:16];
pp_o <= r_mpy_a_input[31:16] * r_mpy_b_input[15: 0];
pp_i <= r_mpy_a_input[15: 0] * r_mpy_b_input[31:16];
pp_l <= r_mpy_a_input[15: 0] * r_mpy_b_input[15: 0];
 
always @(posedge i_clk)
begin
o_r[31: 0] <= partial_mpy_2lo[31:0];
o_r[63:32] <= partial_mpy_2hi
+ { 13'h0, partial_mpy_2ch, 1'b0,
15'h0, partial_mpy_2cl };
o_sync <= r_s[3];
end
if (r_mpy_signed)
pp_s <= 32'h8000_0000 - (r_mpy_a_input[31:0]
+ r_mpy_b_input[31:0]);
else
pp_s <= 33'h0;
r_s[1] <= r_s[0];
end
 
reg [32:0] partial_mpy_oi, partial_mpy_lo;
reg [31:0] partial_mpy_hi;
always @(posedge i_clk)
begin
partial_mpy_lo[30: 0] <= pp_l[30:0];
partial_mpy_lo[32:31] <= pp_s[0] + pp_l[31];
partial_mpy_oi[32: 0] <= pp_o + pp_i;
partial_mpy_hi[31: 0] <= pp_s[32:1] + pp_f;
r_s[2] <= r_s[1];
end
 
reg partial_mpy_2cl, partial_mpy_2ch;
reg [31:0] partial_mpy_2lo, partial_mpy_2hi;
always @(posedge i_clk)
begin
partial_mpy_2lo[15:0] <= partial_mpy_lo[15:0];
{ partial_mpy_2cl, partial_mpy_2lo[31:16] }
<= { 1'b0, partial_mpy_oi[15:0]}
+ partial_mpy_lo[32:16];
{ partial_mpy_2ch, partial_mpy_2hi[16:0] }
<= partial_mpy_oi[32:16] + partial_mpy_hi[16:0];
partial_mpy_2hi[31:16] <= { partial_mpy_2hi[31:17],
1'b0 };
r_s[3] <= r_s[2];
end
 
always @(posedge i_clk)
begin
o_r[31: 0] <= partial_mpy_2lo[31:0];
o_r[63:32] <= partial_mpy_2hi
+ { 14'h0, partial_mpy_2ch, 1'b0,
15'h0, partial_mpy_2cl };
o_sync <= r_s[3];
end
end endgenerate
 
 
endmodule
/openarty/trunk/rtl/wbm2axisp.v
0,0 → 1,390
////////////////////////////////////////////////////////////////////////////////
//
// Filename: wbm2axisp.v
//
// Project: Pipelined Wishbone to AXI converter
//
// Purpose: The B4 Wishbone SPEC allows transactions at a speed as fast as
// one per clock. The AXI bus allows transactions at a speed of
// one read and one write transaction per clock. These capabilities work
// by allowing requests to take place prior to responses, such that the
// requests might go out at once per clock and take several clocks, and
// the responses may start coming back several clocks later. In other
// words, both protocols allow multiple transactions to be "in flight" at
// the same time. Current wishbone to AXI converters, however, handle only
// one transaction at a time: initiating the transaction, and then waiting
// for the transaction to complete before initiating the next.
//
// The purpose of this core is to maintain the speed of both busses, while
// transiting from the Wishbone (as master) to the AXI bus (as slave) and
// back again.
//
// Since the AXI bus allows transactions to be reordered, whereas the
// wishbone does not, this core can be configured to reorder return
// transactions as well.
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Technology, LLC
//
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 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 wbm2axisp #(
parameter C_AXI_ID_WIDTH = 6, // The AXI id width used for R&W
// This is an int between 1-16
parameter C_AXI_DATA_WIDTH = 128,// Width of the AXI R&W data
parameter C_AXI_ADDR_WIDTH = 28, // AXI Address width
parameter DW = 32, // Wishbone data width
parameter AW = 26, // Wishbone address width
parameter STRICT_ORDER = 0 // Reorder, or not? 0 -> Reorder
) (
input i_clk, // System clock
// input i_reset,// Wishbone reset signal--unused
 
// AXI write address channel signals
input i_axi_awready, // Slave is ready to accept
output reg [C_AXI_ID_WIDTH-1:0] o_axi_awid, // Write ID
output reg [C_AXI_ADDR_WIDTH-1:0] o_axi_awaddr, // Write address
output wire [7:0] o_axi_awlen, // Write Burst Length
output wire [2:0] o_axi_awsize, // Write Burst size
output wire [1:0] o_axi_awburst, // Write Burst type
output wire [0:0] o_axi_awlock, // Write lock type
output wire [3:0] o_axi_awcache, // Write Cache type
output wire [2:0] o_axi_awprot, // Write Protection type
output wire [3:0] o_axi_awqos, // Write Quality of Svc
output reg o_axi_awvalid, // Write address valid
// AXI write data channel signals
input i_axi_wready, // Write data ready
output reg [C_AXI_DATA_WIDTH-1:0] o_axi_wdata, // Write data
output reg [C_AXI_DATA_WIDTH/8-1:0] o_axi_wstrb, // Write strobes
output wire o_axi_wlast, // Last write transaction
output reg o_axi_wvalid, // Write valid
// AXI write response channel signals
input [C_AXI_ID_WIDTH-1:0] i_axi_bid, // Response ID
input [1:0] i_axi_bresp, // Write response
input i_axi_bvalid, // Write reponse valid
output wire o_axi_bready, // Response ready
// AXI read address channel signals
input i_axi_arready, // Read address ready
output wire [C_AXI_ID_WIDTH-1:0] o_axi_arid, // Read ID
output wire [C_AXI_ADDR_WIDTH-1:0] o_axi_araddr, // Read address
output wire [7:0] o_axi_arlen, // Read Burst Length
output wire [2:0] o_axi_arsize, // Read Burst size
output wire [1:0] o_axi_arburst, // Read Burst type
output wire [0:0] o_axi_arlock, // Read lock type
output wire [3:0] o_axi_arcache, // Read Cache type
output wire [2:0] o_axi_arprot, // Read Protection type
output wire [3:0] o_axi_arqos, // Read Protection type
output reg o_axi_arvalid, // Read address valid
// AXI read data channel signals
input [C_AXI_ID_WIDTH-1:0] i_axi_rid, // Response ID
input [1:0] i_axi_rresp, // Read response
input i_axi_rvalid, // Read reponse valid
input [C_AXI_DATA_WIDTH-1:0] i_axi_rdata, // Read data
input i_axi_rlast, // Read last
output wire o_axi_rready, // Read Response ready
 
// We'll share the clock and the reset
input i_wb_cyc,
input i_wb_stb,
input i_wb_we,
input [(AW-1):0] i_wb_addr,
input [(DW-1):0] i_wb_data,
input [(DW/8-1):0] i_wb_sel,
output reg o_wb_ack,
output wire o_wb_stall,
output reg [(DW-1):0] o_wb_data,
output reg o_wb_err,
 
output wire [31:0] o_dbg
);
 
//*****************************************************************************
// Parameter declarations
//*****************************************************************************
 
localparam CTL_SIG_WIDTH = 3; // Control signal width
localparam RD_STS_WIDTH = 16; // Read status signal width
localparam WR_STS_WIDTH = 16; // Write status signal width
 
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
 
// Things we're not changing ...
assign o_axi_awlen = 8'h0; // Burst length is one
assign o_axi_awsize = 3'b101; // maximum bytes per burst is 32
assign o_axi_awburst = 2'b01; // Incrementing address (ignored)
assign o_axi_arburst = 2'b01; // Incrementing address (ignored)
assign o_axi_awlock = 1'b0; // Normal signaling
assign o_axi_arlock = 1'b0; // Normal signaling
assign o_axi_awcache = 4'h2; // Normal: no cache, no buffer
assign o_axi_arcache = 4'h2; // Normal: no cache, no buffer
assign o_axi_awprot = 3'b010; // Unpriviledged, unsecure, data access
assign o_axi_arprot = 3'b010; // Unpriviledged, unsecure, data access
assign o_axi_awqos = 4'h0; // Lowest quality of service (unused)
assign o_axi_arqos = 4'h0; // Lowest quality of service (unused)
 
// Command logic
// Write address logic
 
always @(posedge i_clk)
o_axi_awvalid <= (!o_wb_stall)&&(i_wb_stb)&&(i_wb_we)
||(o_wb_stall)&&(o_axi_awvalid)&&(!i_axi_awready);
 
generate
if (DW == 32)
begin
always @(posedge i_clk)
if (!o_wb_stall) // 26 bit address becomes 28 bit ...
o_axi_awaddr <= { i_wb_addr[AW-1:2], 4'b00 };
end else if (DW == 128)
begin
always @(posedge i_clk)
if (!o_wb_stall) // 28 bit address ...
o_axi_awaddr <= { i_wb_addr[AW-1:0], 4'b00 };
end endgenerate
 
reg [5:0] transaction_id;
always @(posedge i_clk)
if (!i_wb_cyc)
transaction_id <= 6'h00;
else if ((i_wb_stb)&&(~o_wb_stall))
transaction_id <= transaction_id + 6'h01;
always @(posedge i_clk)
if ((i_wb_stb)&&(~o_wb_stall))
o_axi_awid <= transaction_id;
 
// Read address logic
assign o_axi_arid = o_axi_awid;
assign o_axi_araddr = o_axi_awaddr;
assign o_axi_arlen = o_axi_awlen;
assign o_axi_arsize = 3'b101; // maximum bytes per burst is 32
always @(posedge i_clk)
o_axi_arvalid <= (!o_wb_stall)&&(i_wb_stb)&&(!i_wb_we)
||(o_wb_stall)&&(o_axi_arvalid)&&(!i_axi_arready);
 
 
// Write data logic
generate
if (DW == 32)
begin
always @(posedge i_clk)
if (!o_wb_stall)
o_axi_wdata <= { i_wb_data, i_wb_data, i_wb_data, i_wb_data };
always @(posedge i_clk)
if (!o_wb_stall)
case(i_wb_addr[1:0])
2'b00:o_axi_wstrb<={ 4'h0, 4'h0, 4'h0,i_wb_sel};
2'b01:o_axi_wstrb<={ 4'h0, 4'h0,i_wb_sel, 4'h0};
2'b10:o_axi_wstrb<={ 4'h0,i_wb_sel, 4'h0, 4'h0};
2'b11:o_axi_wstrb<={i_wb_sel, 4'h0, 4'h0, 4'h0};
endcase
end else if (DW == 128)
begin
always @(posedge i_clk)
if (!o_wb_stall)
o_axi_wdata <= i_wb_data;
always @(posedge i_clk)
if (!o_wb_stall)
o_axi_wstrb <= i_wb_sel;
end endgenerate
 
assign o_axi_wlast = 1'b1;
always @(posedge i_clk)
o_axi_wvalid <= ((!o_wb_stall)&&(i_wb_stb)&&(i_wb_we))
||(o_wb_stall)&&(o_axi_wvalid)&&(!i_axi_wready);
 
// Read data channel / response logic
assign o_axi_rready = 1'b1;
assign o_axi_bready = 1'b1;
 
wire w_fifo_full;
generate
if (STRICT_ORDER == 0)
begin
// Reorder FIFO
//
localparam LGFIFOLN = C_AXI_ID_WIDTH;
localparam FIFOLN = (1<<LGFIFOLN);
// FIFO reorder buffer
reg [(LGFIFOLN-1):0] fifo_tail;
reg [(C_AXI_DATA_WIDTH-1):0] reorder_fifo_data [0:(FIFOLN-1)];
reg [(FIFOLN-1):0] reorder_fifo_valid;
reg [(FIFOLN-1):0] reorder_fifo_err;
 
initial reorder_fifo_valid = 0;
initial reorder_fifo_err = 0;
 
if (DW == 32)
begin
reg [1:0] reorder_fifo_addr [0:(FIFOLN-1)];
 
 
reg [1:0] low_addr;
always @(posedge i_clk)
if ((i_wb_stb)&&(!o_wb_stall))
low_addr <= i_wb_addr[1:0];
always @(posedge i_clk)
if ((o_axi_arvalid)&&(i_axi_arready))
reorder_fifo_addr[o_axi_arid] <= low_addr;
 
always @(posedge i_clk)
case(reorder_fifo_addr[fifo_tail][1:0])
2'b00: o_wb_data <=reorder_fifo_data[fifo_tail][ 31: 0];
2'b01: o_wb_data <=reorder_fifo_data[fifo_tail][ 63:32];
2'b10: o_wb_data <=reorder_fifo_data[fifo_tail][ 95:64];
2'b11: o_wb_data <=reorder_fifo_data[fifo_tail][127:96];
endcase
 
end else if (DW == 128)
begin
always @(posedge i_clk)
o_wb_data <= reorder_fifo_data[fifo_tail];
end
 
 
wire [(LGFIFOLN-1):0] fifo_head;
assign fifo_head = transaction_id;
 
// Let's do some math to figure out where the FIFO head will
// point to next, but let's also insist that it be LGFIFOLN
// bits in size as well. This'll be part of the fifo_full
// calculation below.
wire [(LGFIFOLN-1):0] n_fifo_head, nn_fifo_head;
assign n_fifo_head = fifo_head+1'b1;
assign nn_fifo_head = { fifo_head[(LGFIFOLN-1):1]+1'b1, fifo_head[0] };
 
always @(posedge i_clk)
begin
if ((i_axi_rvalid)&&(o_axi_rready))
reorder_fifo_data[i_axi_rid]<= i_axi_rdata;
if ((i_axi_rvalid)&&(o_axi_rready))
begin
reorder_fifo_valid[i_axi_rid] <= 1'b1;
reorder_fifo_err[i_axi_rid] <= i_axi_rresp[1];
end
if ((i_axi_bvalid)&&(o_axi_bready))
begin
reorder_fifo_valid[i_axi_bid] <= 1'b1;
reorder_fifo_err[i_axi_bid] <= i_axi_bresp[1];
end
 
if (reorder_fifo_valid[fifo_tail])
begin
o_wb_ack <= 1'b1;
o_wb_err <= reorder_fifo_err[fifo_tail];
fifo_tail <= fifo_tail + 6'h1;
reorder_fifo_valid[fifo_tail] <= 1'b0;
reorder_fifo_err[fifo_tail] <= 1'b0;
end else begin
o_wb_ack <= 1'b0;
o_wb_err <= 1'b0;
end
 
if (!i_wb_cyc)
begin
reorder_fifo_valid <= {(FIFOLN){1'b0}};
reorder_fifo_err <= {(FIFOLN){1'b0}};
fifo_tail <= 6'h0;
o_wb_err <= 1'b0;
o_wb_ack <= 1'b0;
end
end
 
assign o_dbg = {
i_wb_stb, o_wb_stall, o_wb_ack, o_wb_err,
fifo_head, fifo_tail, // 12 bits
{ ((i_axi_rvalid)&&(o_axi_rready)) ? i_axi_rid
: ((i_axi_bvalid)&&(o_axi_bready)) ? i_axi_bid
: 6'hf }, // 6 bits
o_axi_arvalid, i_axi_arready,
o_axi_awvalid, i_axi_awready,
o_axi_wvalid, i_axi_wready, // 28 bits so far ...
i_axi_rvalid, i_axi_bvalid, 2'b00
};
 
 
reg r_fifo_full;
always @(posedge i_clk)
begin
if (!i_wb_cyc)
r_fifo_full <= 1'b0;
else if ((i_wb_stb)&&(~o_wb_stall)
&&(reorder_fifo_valid[fifo_tail]))
r_fifo_full <= (fifo_tail==n_fifo_head);
else if ((i_wb_stb)&&(~o_wb_stall))
r_fifo_full <= (fifo_tail==nn_fifo_head);
else if (reorder_fifo_valid[fifo_tail])
r_fifo_full <= 1'b0;
else
r_fifo_full <= (fifo_tail==n_fifo_head);
end
assign w_fifo_full = r_fifo_full;
end else begin
//
// Strict ordering, but can only read every fourth addresses
//
assign w_fifo_full = 1'b0;
always @(posedge i_clk)
o_wb_data <= i_axi_rdata[31:0];
always @(posedge i_clk)
o_wb_ack <= (i_wb_cyc)&&(
((i_axi_rvalid)&&(o_axi_rready))
||((i_axi_bvalid)&&(o_axi_bready)));
always @(posedge i_clk)
o_wb_err <= (i_wb_cyc)&&((o_wb_err)
||((i_axi_rvalid)&&(i_axi_rresp[1]))
||((i_axi_bvalid)&&(i_axi_bresp[1])));
 
assign o_dbg = {
i_wb_stb, o_wb_stall, o_wb_ack, o_wb_err,
12'h00, // 12 bits
{ ((i_axi_rvalid)&&(o_axi_rready)) ? i_axi_rid
: ((i_axi_bvalid)&&(o_axi_bready)) ? i_axi_bid
: 6'hf }, // 6 bits
o_axi_arvalid, i_axi_arready,
o_axi_awvalid, i_axi_awready,
o_axi_wvalid, i_axi_wready, // 28 bits so far ...
i_axi_rvalid, i_axi_bvalid, 2'b00
};
end endgenerate
 
// Now, the difficult signal ... the stall signal
// Let's build for a single cycle input ... and only stall if something
// outgoing is valid and nothing is ready.
assign o_wb_stall = (i_wb_cyc)&&(
(w_fifo_full)
||((o_axi_awvalid)&&(!i_axi_awready))
||((o_axi_wvalid )&&(!i_axi_wready ))
||((o_axi_arvalid)&&(!i_axi_arready)));
endmodule
 
/openarty/trunk/rtl/fasttop.v
110,37 → 110,20
 
`define FULLCLOCK
// Build our master clock
wire i_clk, clk_for_ddr, mem_serial_clk, mem_serial_clk_inv,
wire s_clk_pll, s_clk, clk_for_ddr, mem_serial_clk, mem_serial_clk_inv,
enet_clk, clk_halfspeed, clk_feedback, clk_locked, clk_unused;
PLLE2_BASE #(
.BANDWIDTH("OPTIMIZED"), // OPTIMIZED, HIGH, LOW
.CLKFBOUT_PHASE(0.0), // Phase off. in deg of CLKFB,(-360-360)
.CLKFBOUT_PHASE(0.0), // Phase offset in degrees of CLKFB, (-360-360)
.CLKIN1_PERIOD(10.0), // Input clock period in ns resolution
`ifdef FULLCLOCK
// CLKOUT0_DIVIDE - CLKOUT5_DIVIDE:
// divide amount for each CLKOUT(1-128)
// CLKOUT0_DIVIDE - CLKOUT5_DIVIDE: divide amount for each CLKOUT(1-128)
.CLKFBOUT_MULT(8), // Multiply value for all CLKOUT (2-64)
.CLKOUT0_DIVIDE(4), // 200 MHz
.CLKOUT1_DIVIDE(1), // 800 MHz clock for DDR memory
.CLKOUT2_DIVIDE(1), // 800 MHz clock to run DDR I/O
.CLKOUT3_DIVIDE(1), // 800MHz clk inv to run DDR I/O
.CLKOUT4_DIVIDE(8), // 100 MHz
.CLKOUT5_DIVIDE(32), // 25 MHz
`else
// 100*64/40 = 160 -- the fastest speed where the UART will
// still work at 4MBaud. Others will still support 115200
// Baud
// 100*64/36 = 177.78
// 100*64/34 = 188.24
// 100*64/33 = 193.94
.CLKFBOUT_MULT(8), // Multiply value for all CLKOUT (2-64)
.CLKOUT0_DIVIDE(5), // 160 MHz
.CLKOUT1_DIVIDE(5), // 160 MHz //Clock too slow for DDR mem
.CLKOUT2_DIVIDE(5), // 160 MHz // Clock too slow for DDR
.CLKOUT3_DIVIDE(5), // 160 MHz // Clock too slow for DDR
.CLKOUT4_DIVIDE(20), // 40 MHz
.CLKOUT5_DIVIDE(5),
`endif
.CLKOUT1_DIVIDE(10), // 80 MHz (Unused)
.CLKOUT2_DIVIDE(16), // 50 MHz (Unused)
.CLKOUT3_DIVIDE(32), // 25 MHz (Unused/Ethernet clock)
.CLKOUT4_DIVIDE(16), // 50 MHz (Unused clock?)
.CLKOUT5_DIVIDE(24),
// CLKOUT0_DUTY_CYCLE -- Duty cycle for each CLKOUT
.CLKOUT0_DUTY_CYCLE(0.5),
.CLKOUT1_DUTY_CYCLE(0.5),
150,9 → 133,9
.CLKOUT5_DUTY_CYCLE(0.5),
// CLKOUT0_PHASE -- phase offset for each CLKOUT
.CLKOUT0_PHASE(0.0),
.CLKOUT1_PHASE(270.0),
.CLKOUT1_PHASE(0.0),
.CLKOUT2_PHASE(0.0),
.CLKOUT3_PHASE(180.0),
.CLKOUT3_PHASE(0.0),
.CLKOUT4_PHASE(0.0),
.CLKOUT5_PHASE(0.0),
.DIVCLK_DIVIDE(1), // Master division value , (1-56)
160,28 → 143,27
.STARTUP_WAIT("TRUE") // Delay DONE until PLL Locks, ("TRUE"/"FALSE")
) genclock(
// Clock outputs: 1-bit (each) output
.CLKOUT0(i_clk),
.CLKOUT1(clk_for_ddr),
.CLKOUT2(mem_serial_clk),
.CLKOUT3(mem_serial_clk_inv),
.CLKOUT4(clk_unused),
.CLKOUT5(enet_clk),
.CLKOUT0(s_clk_pll),
.CLKOUT1(mem_clk),
.CLKOUT2(clk2_unused),
.CLKOUT3(enet_clk),
.CLKOUT4(clk4_unused),
.CLKOUT5(clk5_unused),
.CLKFBOUT(clk_feedback), // 1-bit output, feedback clock
.LOCKED(clk_locked),
.CLKIN1(i_clk_100mhz),
.PWRDWN(1'b0),
.RST(1'b0),
.CLKFBIN(clk_feedback) // 1-bit input, feedback clock
.CLKFBIN(clk_feedback_bufd) // 1-bit input, feedback clock
);
 
// Help reduce skew ...
BUFG sys_clk_buffer( .I(s_clk_pll), .O(s_clk));
BUFG feedback_buffer(.I(clk_feedback),.O(clk_feedback_bufd));
 
// UART interface
wire [29:0] bus_uart_setup;
`ifdef FULLCLOCK
assign bus_uart_setup = 30'h10000032; // 4MBaud, 7 bits
`else
assign bus_uart_setup = 30'h10000028;//4MBaud,7 bits,@160MHzClk
//assign bus_uart_setup = 30'h10000019;//4MBaud,7 bits,@100MHzClk
`endif
assign bus_uart_setup = 30'h10000028; // 4MBaud, 7 bits
 
wire [7:0] rx_data, tx_data;
wire rx_break, rx_parity_err, rx_frame_err, rx_stb;
202,20 → 184,20
// Logic description starts with the PRE-reset, so as to make certain
// we include the reset button
initial pre_reset = 1'b0;
always @(posedge i_clk)
always @(posedge s_clk)
pre_reset <= ~i_reset_btn;
//
// and then continues with the actual reset, now that we've
// synchronized our reset button wire.
initial pwr_reset = 1'b1;
always @(posedge i_clk)
always @(posedge s_clk)
pwr_reset <= pre_reset;
 
wire w_ck_uart, w_uart_tx;
rxuart rcv(i_clk, pwr_reset, bus_uart_setup, i_uart_rx,
rxuart rcv(s_clk, pwr_reset, bus_uart_setup, i_uart_rx,
rx_stb, rx_data, rx_break,
rx_parity_err, rx_frame_err, w_ck_uart);
txuart txv(i_clk, pwr_reset, bus_uart_setup, 1'b0,
txuart txv(s_clk, pwr_reset, bus_uart_setup, 1'b0,
tx_stb, tx_data, o_uart_tx, tx_busy);
 
 
402,11 → 384,14
wire [3:0] i_qspi_dat;
 
//
wire [2:0] w_ddr_dqs;
wire [31:0] wo_ddr_data, wi_ddr_data;
//
wire w_mdio, w_mdwe;
//
wire w_sd_cmd;
wire [3:0] w_sd_data;
fastmaster wbbus(i_clk, pwr_reset,
fastmaster wbbus(s_clk, pwr_reset,
// External USB-UART bus control
rx_stb, rx_data, tx_stb, tx_data, tx_busy,
// Board lights and switches
450,34 → 435,36
// ?? Dual mode out (not yet)
//
//
// `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]));
assign i_qspi_dat = io_qspi_dat;
assign o_qspi_sck = w_qspi_sck;
`else
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 != 2'b11),
xioddr xqspi_d0( s_clk, (qspi_bmod != 2'b11),
{ qspi_dat[0], qspi_dat[0] },
{ i_qspi_pedge[0], i_qspi_nedge[0] }, io_qspi_dat[0]);
xioddr xqspi_d1( i_clk, (qspi_bmod==2'b10),
xioddr xqspi_d1( s_clk, (qspi_bmod==2'b10),
{ qspi_dat[1], qspi_dat[1] },
{ i_qspi_pedge[1], i_qspi_nedge[1] }, io_qspi_dat[1]);
xioddr xqspi_d2( i_clk, (qspi_bmod!=2'b11),
xioddr xqspi_d2( s_clk, (qspi_bmod!=2'b11),
(qspi_bmod[1])?{ qspi_dat[2], qspi_dat[2] }:2'b11,
{ i_qspi_pedge[2], i_qspi_nedge[2] }, io_qspi_dat[2]);
xioddr xqspi_d3( i_clk, (qspi_bmod!=2'b11),
xioddr xqspi_d3( s_clk, (qspi_bmod!=2'b11),
(qspi_bmod[1])?{ qspi_dat[3], qspi_dat[3] }:2'b11,
{ 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
//
//
 
 
//
//
// Wires for setting up the SD Card Controller
/openarty/trunk/rtl/fastio.v
50,7 → 50,8
// Cross-board I/O
i_rtc_ppd, i_buserr, i_other_ints, o_bus_int, o_board_ints);
parameter AUXUART_SETUP = 30'd1736, // 115200 baud from 200MHz clk
GPSUART_SETUP = 30'd20833; // 9600 baud from 200MHz clk
GPSUART_SETUP = 30'd20833, // 9600 baud from 200MHz clk
EXTRACLOCK = 1; // Do we need an extra clock to process?
input i_clk;
// Board level I/O
input [3:0] i_sw;
94,17 → 95,33
output wire o_bus_int;
output wire [5:0] o_board_ints; // Button and switch interrupts
 
reg last_wb_stb;
reg [4:0] last_wb_addr;
reg [31:0] last_wb_data;
initial last_wb_stb = 1'b0;
always @(posedge i_clk)
wire [31:0] w_wb_data;
wire [4:0] w_wb_addr;
wire w_wb_stb;
 
generate
if (EXTRACLOCK == 0)
begin
last_wb_addr <= i_wb_addr;
last_wb_data <= i_wb_data;
last_wb_stb <= (i_wb_stb)&&(i_wb_we);
end
assign w_wb_data = i_wb_data;
assign w_wb_addr = i_wb_addr;
assign w_wb_stb = (i_wb_stb)&&(i_wb_we);
end else begin
reg last_wb_stb;
reg [4:0] last_wb_addr;
reg [31:0] last_wb_data;
initial last_wb_stb = 1'b0;
always @(posedge i_clk)
begin
last_wb_addr <= i_wb_addr;
last_wb_data <= i_wb_data;
last_wb_stb <= (i_wb_stb)&&(i_wb_we);
end
 
assign w_wb_data = last_wb_data;
assign w_wb_addr = last_wb_addr;
assign w_wb_stb = last_wb_stb;
end endgenerate
 
wire [31:0] pic_data;
reg sw_int, btn_int;
wire pps_int, rtc_int, netrx_int, nettx_int,
118,7 → 135,7
// The BUS Interrupt controller
//
icontrol #(15) buspic(i_clk, 1'b0,
(last_wb_stb)&&(last_wb_addr==5'h1),
(w_wb_stb)&&(w_wb_addr==5'h1),
i_wb_data, pic_data,
{ zip_int, oled_int, sd_int,
gpsrx_int, scop_int, flash_int, gpio_int,
152,18 → 169,18
swlast<= swnow;
sw_int <= |((swnow^swlast)|swcfg);
 
if ((last_wb_stb)&&(last_wb_addr == 5'h4))
swcfg <= ((last_wb_data[3:0])&(last_wb_data[11:8]))
|((~last_wb_data[3:0])&(swcfg));
if ((w_wb_stb)&&(w_wb_addr == 5'h4))
swcfg <= ((w_wb_data[3:0])&(w_wb_data[11:8]))
|((~w_wb_data[3:0])&(swcfg));
 
r_btn <= i_btn;
btnnow <= r_btn;
btn_int <= |(btnnow&btncfg);
if ((last_wb_stb)&&(last_wb_addr == 5'h4))
if ((w_wb_stb)&&(w_wb_addr == 5'h4))
begin
btncfg <= ((last_wb_data[7:4])&(last_wb_data[15:12]))
|((~last_wb_data[7:4])&(btncfg));
btnstate<= (btnnow)|((btnstate)&(~last_wb_data[7:4]));
btncfg <= ((w_wb_data[7:4])&(w_wb_data[15:12]))
|((~w_wb_data[7:4])&(btncfg));
btnstate<= (btnnow)|((btnstate)&(~w_wb_data[7:4]));
end else
btnstate <= (btnstate)|(btnnow);
end
174,14 → 191,11
//
reg [3:0] r_leds;
wire [31:0] w_ledreg;
reg last_cyc;
always @(posedge i_clk)
last_cyc <= i_wb_cyc;
initial r_leds = 4'h0;
always @(posedge i_clk)
if ((last_wb_stb)&&(last_wb_addr == 5'h5))
r_leds <= ((last_wb_data[7:4])&(last_wb_data[3:0]))
|((~last_wb_data[7:4])&(r_leds));
if ((w_wb_stb)&&(w_wb_addr == 5'h5))
r_leds <= ((w_wb_data[7:4])&(w_wb_data[3:0]))
|((~w_wb_data[7:4])&(r_leds));
assign o_led = r_leds;
assign w_ledreg = { 28'h0, r_leds };
 
202,8 → 216,8
reg [29:0] aux_setup;
initial aux_setup = AUXUART_SETUP;
always @(posedge i_clk)
if ((last_wb_stb)&&(last_wb_addr == 5'h6))
aux_setup[29:0] <= last_wb_data[29:0];
if ((w_wb_stb)&&(w_wb_addr == 5'h6))
aux_setup[29:0] <= w_wb_data[29:0];
 
//
// GPSSETUP
212,8 → 226,8
reg [29:0] gps_setup;
initial gps_setup = GPSUART_SETUP;
always @(posedge i_clk)
if ((last_wb_stb)&&(last_wb_addr == 5'h7))
gps_setup[29:0] <= last_wb_data[29:0];
if ((w_wb_stb)&&(w_wb_addr == 5'h7))
gps_setup[29:0] <= w_wb_data[29:0];
 
//
// CLR LEDs
226,11 → 240,11
initial r_clr_led0_g = 9'h000;
initial r_clr_led0_b = 9'h000;
always @(posedge i_clk)
if ((last_wb_stb)&&(last_wb_addr == 5'h8))
if ((w_wb_stb)&&(w_wb_addr == 5'h8))
begin
r_clr_led0_r <= { last_wb_data[26], last_wb_data[23:16] };
r_clr_led0_g <= { last_wb_data[25], last_wb_data[15: 8] };
r_clr_led0_b <= { last_wb_data[24], last_wb_data[ 7: 0] };
r_clr_led0_r <= { w_wb_data[26], w_wb_data[23:16] };
r_clr_led0_g <= { w_wb_data[25], w_wb_data[15: 8] };
r_clr_led0_b <= { w_wb_data[24], w_wb_data[ 7: 0] };
end
assign w_clr_led0 = { 5'h0,
r_clr_led0_r[8], r_clr_led0_g[8], r_clr_led0_b[8],
248,11 → 262,11
initial r_clr_led1_g = 9'h000;
initial r_clr_led1_b = 9'h000;
always @(posedge i_clk)
if ((last_wb_stb)&&(last_wb_addr == 5'h9))
if ((w_wb_stb)&&(w_wb_addr == 5'h9))
begin
r_clr_led1_r <= { last_wb_data[26], last_wb_data[23:16] };
r_clr_led1_g <= { last_wb_data[25], last_wb_data[15: 8] };
r_clr_led1_b <= { last_wb_data[24], last_wb_data[ 7: 0] };
r_clr_led1_r <= { w_wb_data[26], w_wb_data[23:16] };
r_clr_led1_g <= { w_wb_data[25], w_wb_data[15: 8] };
r_clr_led1_b <= { w_wb_data[24], w_wb_data[ 7: 0] };
end
assign w_clr_led1 = { 5'h0,
r_clr_led1_r[8], r_clr_led1_g[8], r_clr_led1_b[8],
269,11 → 283,11
initial r_clr_led2_g = 9'h000;
initial r_clr_led2_b = 9'h000;
always @(posedge i_clk)
if ((last_wb_stb)&&(last_wb_addr == 5'ha))
if ((w_wb_stb)&&(w_wb_addr == 5'ha))
begin
r_clr_led2_r <= { last_wb_data[26], last_wb_data[23:16] };
r_clr_led2_g <= { last_wb_data[25], last_wb_data[15: 8] };
r_clr_led2_b <= { last_wb_data[24], last_wb_data[ 7: 0] };
r_clr_led2_r <= { w_wb_data[26], w_wb_data[23:16] };
r_clr_led2_g <= { w_wb_data[25], w_wb_data[15: 8] };
r_clr_led2_b <= { w_wb_data[24], w_wb_data[ 7: 0] };
end
assign w_clr_led2 = { 5'h0,
r_clr_led2_r[8], r_clr_led2_g[8], r_clr_led2_b[8],
290,11 → 304,11
initial r_clr_led3_g = 9'h000;
initial r_clr_led3_b = 9'h000;
always @(posedge i_clk)
if ((last_wb_stb)&&(last_wb_addr == 5'hb))
if ((w_wb_stb)&&(w_wb_addr == 5'hb))
begin
r_clr_led3_r <= { last_wb_data[26], last_wb_data[23:16] };
r_clr_led3_g <= { last_wb_data[25], last_wb_data[15: 8] };
r_clr_led3_b <= { last_wb_data[24], last_wb_data[ 7: 0] };
r_clr_led3_r <= { w_wb_data[26], w_wb_data[23:16] };
r_clr_led3_g <= { w_wb_data[25], w_wb_data[15: 8] };
r_clr_led3_b <= { w_wb_data[24], w_wb_data[ 7: 0] };
end
assign w_clr_led3 = { 5'h0,
r_clr_led3_r[8], r_clr_led3_g[8], r_clr_led3_b[8],
313,7 → 327,7
`ifdef GET_DATE
wire date_ack, date_stall;
rtcdate thedate(i_clk, i_rtc_ppd,
i_wb_cyc, last_wb_stb, (last_wb_addr==5'hc), last_wb_data,
i_wb_cyc, w_wb_stb, (w_wb_addr==5'hc), w_wb_data,
date_ack, date_stall, date_data);
`else
assign date_data = 32'h20160000;
346,7 → 360,7
end
always @(posedge i_clk)
if(((i_wb_stb)&&(~i_wb_we)&&(i_wb_addr == 5'h0e))||(auxrx_stb))
r_auxrx_data[8] <= auxrx_stb;
r_auxrx_data[8] <= !auxrx_stb;
assign o_aux_cts = auxrx_stb;
assign auxrx_data = { 20'h00, r_auxrx_data };
assign auxrx_int = r_auxrx_data[8];
362,11 → 376,11
r_auxtx_break, r_auxtx_stb, r_auxtx_data,
o_aux_tx, auxtx_busy);
always @(posedge i_clk)
if ((last_wb_stb)&&(last_wb_addr == 5'h0f))
if ((w_wb_stb)&&(w_wb_addr == 5'h0f))
begin
r_auxtx_stb <= 1'b1;
r_auxtx_data <= last_wb_data[7:0];
r_auxtx_break<= last_wb_data[9];
r_auxtx_stb <= (!r_auxtx_break)&&(!w_wb_data[9]);
r_auxtx_data <= w_wb_data[7:0];
r_auxtx_break<= w_wb_data[9];
end else if (~auxtx_busy)
begin
r_auxtx_stb <= 1'b0;
416,11 → 430,11
r_gpstx_break, r_gpstx_stb, r_gpstx_data,
o_gps_tx, gpstx_busy);
always @(posedge i_clk)
if ((last_wb_stb)&&(last_wb_addr == 5'h11))
if ((w_wb_stb)&&(w_wb_addr == 5'h11))
begin
r_gpstx_stb <= 1'b1;
r_gpstx_data <= last_wb_data[7:0];
r_gpstx_break<= last_wb_data[9];
r_gpstx_data <= w_wb_data[7:0];
r_gpstx_break<= w_wb_data[9];
end else if (~gpstx_busy)
begin
r_gpstx_stb <= 1'b0;
/openarty/trunk/rtl/txuart.v
167,6 → 167,7
// baud_counter <= 0;
r_setup <= i_setup;
calc_parity <= 1'b0;
lcl_data <= i_data;
if ((i_wr)&&(~r_busy))
begin // Immediately start us off with a start bit
o_uart <= 1'b0;
177,12 → 178,10
2'b10: state <= `TXU_BIT_TWO;
2'b11: state <= `TXU_BIT_THREE;
endcase
lcl_data <= i_data;
// baud_counter <= clocks_per_baud-28'h01;
end else begin // Stay in idle
o_uart <= 1'b1;
r_busy <= 0;
// lcl_data is irrelevant
// state <= state;
end
end else begin
227,7 → 226,8
assign o_busy = (r_busy);
 
 
initial zero_baud_counter = 1'b0;
initial zero_baud_counter = 1'b1;
initial baud_counter = 28'd200000; // 1ms @ 200MHz
always @(posedge i_clk)
begin
zero_baud_counter <= (baud_counter == 28'h01);
/openarty/trunk/rtl/builddate.v
38,4 → 38,4
////////////////////////////////////////////////////////////////////////////////
//
//
`define DATESTAMP 32'h20160811
`define DATESTAMP 32'h20160909
/openarty/trunk/rtl/wbscope.v
101,17 → 101,6
// 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)];
 
122,13 → 111,13
wire [19:0] bw_holdoff;
initial br_config = ((1<<(LGMEM-1))-4);
always @(posedge i_wb_clk)
if ((r_wb_stb)&&(~r_wb_addr))
if ((i_wb_cyc)&&(i_wb_stb)&&(~i_wb_addr))
begin
if (r_wb_we)
br_config <= { r_wb_data[31],
(r_wb_data[27]),
r_wb_data[26],
r_wb_data[19:0] };
if (i_wb_we)
br_config <= { i_wb_data[31],
(i_wb_data[27]),
i_wb_data[26],
i_wb_data[19:0] };
end else if (bw_reset_complete)
br_config[22] <= 1'b1;
assign bw_reset_request = (~br_config[22]);
200,14 → 189,11
// Determine when memory is full and capture is complete
//
// Writes take place on the data clock
reg dr_stopped, dr_past_holdoff;
reg dr_stopped;
reg [19:0] counter; // This is unsigned
initial dr_stopped = 1'b0;
initial counter = 20'h0000;
initial dr_past_holdoff = 1'b0;
always @(posedge i_clk)
dr_past_holdoff <= (counter >= bw_holdoff);
always @(posedge i_clk)
if (dw_reset)
begin
counter <= 0;
216,9 → 202,10
begin // MUST BE a < and not <=, so that we can keep this w/in
// 20 bits. Else we'd need to add a bit to comparison
// here.
if (~dr_stopped)
if (counter < bw_holdoff)
counter <= counter + 20'h01;
dr_stopped <= (dr_stopped)||(dr_past_holdoff);
else
dr_stopped <= 1'b1;
end
 
//
239,7 → 226,7
begin
waddr <= 0; // upon reset.
dr_primed <= 1'b0;
end else if ((i_ce)&&(~dr_stopped))
end else if ((i_ce)&&((~dr_triggered)||(counter < bw_holdoff)))
begin
// mem[waddr] <= i_data;
waddr <= waddr + {{(LGMEM-1){1'b0}},1'b1};
246,7 → 233,7
dr_primed <= (dr_primed)||(&waddr);
end
always @(posedge i_clk)
if ((i_ce)&&(~dr_stopped))
if ((i_ce)&&((~dr_triggered)||(counter < bw_holdoff)))
mem[waddr] <= i_data;
 
//
284,50 → 271,38
end endgenerate
 
// Reads use the bus clock
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);
reg br_wb_ack;
initial br_wb_ack = 1'b0;
wire bw_cyc_stb;
assign bw_cyc_stb = ((i_wb_cyc)&&(i_wb_stb));
always @(posedge i_wb_clk)
begin // CE depends upon 5 inputs, output on 7 (ignoring add&carries)
if ((bw_reset_request)||(bus_write_fifo))
begin
if ((bw_reset_request)
||((bw_cyc_stb)&&(i_wb_addr)&&(i_wb_we)))
raddr <= 0;
else if ((bus_read_fifo)&&(bw_stopped))
else if ((bw_cyc_stb)&&(i_wb_addr)&&(~i_wb_we)&&(bw_stopped))
raddr <= raddr + {{(LGMEM-1){1'b0}},1'b1}; // Data read, when stopped
 
r_wb_ack <= r_wb_stb;
s_wb_ack <= r_wb_ack;
br_wb_ack <= s_wb_ack;
if ((bw_cyc_stb)&&(~i_wb_we))
begin // Read from the bus
br_wb_ack <= 1'b1;
end else if ((bw_cyc_stb)&&(i_wb_we))
// We did this write above
br_wb_ack <= 1'b1;
else // Do nothing if either i_wb_cyc or i_wb_stb are low
br_wb_ack <= 1'b0;
end
 
reg [(LGMEM-1):0] nxt_addr;
always @(posedge i_wb_clk) // 2 adds, then 5 inputs
if (bus_read_fifo)
nxt_addr <= nxt_addr + {{(LGMEM-1){1'b0}},1'b1};
else
nxt_addr <= raddr + waddr;
// nxt_addr <= raddr + waddr + (bus_read_fifo)
// ? {{(LGMEM-1){1'b0}},1'b1}: 0;
 
reg [31:0] nxt_mem;
always @(posedge i_wb_clk)
nxt_mem <= mem[nxt_addr];
nxt_mem <= mem[raddr+waddr+
(((bw_cyc_stb)&&(i_wb_addr)&&(~i_wb_we)) ?
{{(LGMEM-1){1'b0}},1'b1} : { (LGMEM){1'b0}} )];
 
always @(posedge i_clk)
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 (~q_wb_addr) // Control register read
if (~i_wb_addr) // Control register read
o_wb_data <= { bw_reset_request,
bw_stopped,
bw_triggered,
343,7 → 318,7
o_wb_data <= nxt_mem; // mem[raddr+waddr];
 
assign o_wb_stall = 1'b0;
assign o_wb_ack = (s_wb_ack);
assign o_wb_ack = (i_wb_cyc)&&(br_wb_ack);
 
reg br_level_interrupt;
initial br_level_interrupt = 1'b0;
/openarty/trunk/rtl/wbicapetwo.v
96,6 → 96,7
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_dbg);
parameter LGDIV = 3; /// Log of the clock divide
input i_clk;
// Wishbone inputs
input i_wb_cyc, i_wb_stb, i_wb_we;
113,38 → 114,45
reg [31:0] r_data;
reg [4:0] r_addr;
 
`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)
generate
if (LGDIV <= 1)
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 r_slow_clk;
always @(posedge i_clk)
begin
r_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 1ckcycle
end
 
assign slow_clk = r_slow_clk;
end else begin
reg [(LGDIV-1):0] slow_clk_counter;
 
always @(posedge i_clk)
begin
slow_clk_counter <= slow_clk_counter + 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_counter=={{(LGDIV){1'b1}},1'b0});
// CLK_STALL is set to true two clocks before any cycle that
// will, by necessity, stall.
clk_stall <= (slow_clk_counter!={{(LGDIV){1'b0}},1'b1});
end
 
assign slow_clk = slow_clk_counter[(LGDIV-1)];
end endgenerate
 
reg [31:0] cfg_in;
reg cfg_cs_n, cfg_rdwrn;
wire [31:0] cfg_out;
/openarty/trunk/rtl/busmaster.v
40,12 → 40,6
//
`define NO_ZIP_WBU_DELAY
`define ZIPCPU
`ifdef ZIPCPU
`define ZIP_SYSTEM
`ifndef ZIP_SYSTEM
`define ZIP_BONES
`endif // ZIP_SYSTEM
`endif // ZipCPU
//
//
`define SDCARD_ACCESS
54,7 → 48,7
`define ICAPE_ACCESS
`endif
`define FLASH_ACCESS
//`define SDRAM_ACCESS
`define SDRAM_ACCESS
`define GPS_CLOCK
// UART_ACCESS and GPS_UART have both been placed within fastio
// `define UART_ACCESS
62,10 → 56,43
`define RTC_ACCESS
`define OLEDRGB_ACCESS
//
// `define CPU_SCOPE
// `define GPS_SCOPE
`define FLASH_SCOPE
// `define SDRAM_SCOPE
//
//
//
//
// Now, conditional compilation based upon what capabilities we have turned
// on
//
`ifdef ZIPCPU
`define ZIP_SYSTEM
`ifndef ZIP_SYSTEM
`define ZIP_BONES
`endif // ZIP_SYSTEM
`endif // ZipCPU
//
//
// SCOPE POSITION ZERO
//
`ifdef FLASH_ACCESS
`define FLASH_SCOPE // Position zero
`else
`ifdef ZIPCPU
// `define CPU_SCOPE // Position zero
`endif
`endif
//
// SCOPE POSITION ONE
//
// `define GPS_SCOPE // Position one
`ifdef ICAPE_ACCESS
`define CFG_SCOPE // Position one
`endif
//
// SCOPE POSITION TWO
//
`ifdef SDRAM_ACCESS
`define SDRAM_SCOPE // Position two
`endif
// `define ENET_SCOPE
//
//
80,9 → 107,16
// The Quad SPI Flash
o_qspi_cs_n, o_qspi_sck, o_qspi_dat, i_qspi_dat, o_qspi_mod,
// The DDR3 SDRAM
o_ddr_reset_n, o_ddr_cke,
o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
o_ddr_dqs, o_ddr_addr, o_ddr_ba, o_ddr_data, i_ddr_data,
// The actual wires need to be controlled from the device
// dependent file. In order to keep this device independent,
// we export only the wishbone interface to the RAM.
// o_ddr_ck_p, o_ddr_ck_n, o_ddr_reset_n, o_ddr_cke,
// o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
// o_ddr_ba, o_ddr_addr, o_ddr_odt, o_ddr_dm,
// io_ddr_dqs_p, io_ddr_dqs_n, io_ddr_data,
o_ram_cyc, o_ram_stb, o_ram_we, o_ram_addr, o_ram_wdata,
i_ram_ack, i_ram_stall, i_ram_rdata, i_ram_err,
i_ram_dbg,
// The SD Card
o_sd_sck, o_sd_cmd, o_sd_data, i_sd_cmd, i_sd_data, i_sd_detect,
// Ethernet control (MDIO) lines
93,8 → 127,8
// The GPS PMod
i_gps_pps, i_gps_3df
);
parameter ZA=24, ZIPINTS=13;
input i_clk, i_rst;
parameter ZA=24, ZIPINTS=14;
input i_clk, i_rst;
// The bus commander, via an external uart port
input i_rx_stb;
input [7:0] i_rx_data;
116,14 → 150,31
output wire [3:0] o_qspi_dat;
input [3:0] i_qspi_dat;
output wire [1:0] o_qspi_mod;
//
// DDR3 RAM controller
output wire o_ddr_reset_n, o_ddr_cke,
o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n,o_ddr_we_n;
output wire [2:0] o_ddr_dqs;
output wire [13:0] o_ddr_addr;
output wire [2:0] o_ddr_ba;
output wire [31:0] o_ddr_data;
input [31:0] i_ddr_data;
//
// These would be our RAM control lines. However, these are device,
// implementation, and architecture dependent, rather than just simply
// logic dependent. Therefore, this interface as it exists cannot
// exist here. Instead, we export a device independent wishbone to
// the RAM rather than the RAM wires themselves.
//
// output wire o_ddr_ck_p, o_ddr_ck_n,o_ddr_reset_n, o_ddr_cke,
// o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n,o_ddr_we_n;
// output wire [2:0] o_ddr_ba;
// output wire [13:0] o_ddr_addr;
// output wire o_ddr_odt;
// output wire [1:0] o_ddr_dm;
// inout wire [1:0] io_ddr_dqs_p, io_ddr_dqs_n;
// inout wire [15:0] io_ddr_data;
//
output wire o_ram_cyc, o_ram_stb, o_ram_we;
output wire [25:0] o_ram_addr;
output wire [31:0] o_ram_wdata;
input i_ram_ack, i_ram_stall;
input [31:0] i_ram_rdata;
input i_ram_err;
input [31:0] i_ram_dbg;
// The SD Card
output wire o_sd_sck;
output wire o_sd_cmd;
147,7 → 198,7
// Master wishbone wires
//
//
wire wb_cyc, wb_stb, wb_we, wb_stall, wb_err;
wire wb_cyc, wb_stb, wb_we, wb_stall, wb_err, ram_err;
wire [31:0] wb_data, wb_addr;
reg wb_ack;
reg [31:0] wb_idata;
375,16 → 426,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 }
394,7 → 446,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)
409,12 → 461,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
432,20 → 481,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
465,7 → 512,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
545,7 → 592,7
||((single_sel_a)&&(single_sel_b))
||((single_sel_a)&&(many_sel_a))
||((single_sel_b)&&(many_sel_b));
assign wb_err = (wb_cyc)&&(sel_err || many_ack || slow_many_ack);
assign wb_err = (wb_cyc)&&(sel_err || many_ack || slow_many_ack||ram_err);
 
 
// Finally, if we ever encounter a bus error, knowing the address of
579,8 → 626,9
wire [3:0] w_led;
wire rtc_ppd;
fastio #(
.AUXUART_SETUP(30'hd50),
.GPSUART_SETUP(30'hd20833)
.AUXUART_SETUP(30'hd705), // 115200 Baud, 8N1, from 81.25M
.GPSUART_SETUP(30'hd8464), // 9600 Baud, 8N1
.EXTRACLOCK(0)
) runio(i_clk, i_sw, i_btn,
w_led, o_clr_led0, o_clr_led1, o_clr_led2, o_clr_led3,
i_aux_rx, o_aux_tx, o_aux_cts, i_gps_rx, o_gps_tx,
632,7 → 680,11
wire gps_tracking, ck_pps;
wire [63:0] gps_step;
`ifdef RTC_ACCESS
rtcgps #(32'h15798f) // 2^48 / 200MHz
rtcgps
// #(32'h15798f) // 2^48 / 200MHz
// #(32'h1a6e3a) // 2^48 / 162.5 MHz
#(32'h34dc74) // 2^48 / 81.25MHz
// #(32'h35afe6) // 2^48 / 80.0 MHz
thertc(i_clk,
wb_cyc, (wb_stb)&&(rtc_sel), wb_we,
wb_addr[1:0], wb_data,
743,7 → 795,9
//
// GPS CLOCK CONTROL
//
gpsclock ppsck(i_clk, 1'b0, gps_pps, ck_pps, gps_led,
gpsclock #(
.DEFAULT_STEP(32'h834d_c736)
) ppsck(i_clk, 1'b0, gps_pps, ck_pps, gps_led,
(wb_stb)&&(gps_sel)&&(~wb_addr[3]),
wb_we, wb_addr[1:0],
wb_data, gck_ack, gck_stall, gck_data,
795,7 → 849,7
assign enet_rx_int = 1'b0;
assign enet_tx_int = 1'b0;
 
enetctrl #(3)
enetctrl #(2)
mdio(i_clk, i_rst, wb_cyc, (wb_stb)&&(netb_sel), wb_we,
wb_addr[4:0], wb_data[15:0],
netb_ack, netb_stall, netb_data,
836,9 → 890,11
// MULTIBOOT/ICAPE2 CONFIGURATION ACCESS
//
`ifdef ICAPE_ACCESS
wbicapetwo fpga_cfg(i_clk, wb_cyc,(cfg_sel)&&(wb_stb), wb_we,
wire [31:0] cfg_debug;
wbicapetwo #(.LGDIV(1)) // Divide the clock by two
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)
853,7 → 909,8
//
// There is no option to turn this off--this RAM must always be
// present in the design.
memdev #(15) // 32kW, or 128kB, 15 address lines
memdev #(.AW(15),
.EXTRACLOCK(0)) // 32kW, or 128kB, 15 address lines
blkram(i_clk, wb_cyc, (wb_stb)&&(mem_sel), wb_we, wb_addr[14:0],
wb_data, mem_ack, mem_stall, mem_data);
 
897,13 → 954,39
//
//
`ifdef SDRAM_ACCESS
wbddrsdram rami(i_clk,
//wbddrsdram rami(i_clk,
// wb_cyc, (wb_stb)&&(ram_sel), wb_we, wb_addr[25:0], wb_data,
// ram_ack, ram_stall, ram_data,
// o_ddr_reset_n, o_ddr_cke,
// o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
// o_ddr_dqs,
// o_ddr_addr, o_ddr_ba, o_ddr_data, i_ddr_data);
 
assign o_ram_cyc = wb_cyc;
assign o_ram_stb = (wb_stb)&&(ram_sel);
assign o_ram_we = wb_we;
assign o_ram_addr = wb_addr[25:0];
assign o_ram_wdata = wb_data;
assign ram_ack = i_ram_ack;
assign ram_stall = i_ram_stall;
assign ram_data = i_ram_rdata;
assign ram_err = i_ram_err;
/*
migsdram rami(i_clk, i_memref_clk_200mhz, i_rst,
wb_cyc, (wb_stb)&&(ram_sel), wb_we, wb_addr[25:0], wb_data,
ram_ack, ram_stall, ram_data,
4'hf,
ram_ack, ram_stall, ram_data, ram_err,
//
o_ddr_ck_p, o_ddr_ck_n,
o_ddr_reset_n, o_ddr_cke,
o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
o_ddr_dqs,
o_ddr_addr, o_ddr_ba, o_ddr_data, i_ddr_data);
o_ddr_ba, o_ddr_addr,
o_ddr_odt, o_ddr_dm,
io_ddr_dqs_p, io_ddr_dqs_n,
io_ddr_data,
ram_ready
);
*/
`else
assign ram_data = 32'h00;
assign ram_stall = 1'b0;
947,8 → 1030,8
&&(wb_err)||(zip_scope_data[31]);
wbscope #(5'd13) cpuscope(i_clk, 1'b1,(scop_cpu_trigger), zip_scope_data,
// Wishbone interface
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b00)), wb_we, wb_addr[0],
wb_data,
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b00)),
wb_we, wb_addr[0], wb_data,
scop_cpu_ack, scop_cpu_stall, scop_cpu_data,
scop_cpu_interrupt);
 
966,8 → 1049,8
wbscope #(5'd13) flashscope(i_clk, 1'b1,
(scop_flash_trigger), flash_debug,
// Wishbone interface
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b00)), wb_we, wb_addr[0],
wb_data,
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b00)),
wb_we, wb_addr[0], wb_data,
scop_flash_ack, scop_flash_stall, scop_flash_data,
scop_flash_interrupt);
 
1007,7 → 1090,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;
1017,6 → 1126,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
1024,7 → 1134,26
wire [31:0] scop_c_data;
wire scop_c_ack, scop_c_stall, scop_c_interrupt;
//
//`else
`ifdef SDRAM_SCOPE
wire [31:0] scop_sdram_data;
wire scop_sdram_ack, scop_sdram_stall, scop_sdram_interrupt;
wire sdram_trigger;
wire [31:0] sdram_debug;
assign sdram_trigger = (ram_sel)&&(wb_stb);
assign sdram_debug= i_ram_dbg;
 
wbscope #(5'd10,32,1) ramscope(i_clk, 1'b1, sdram_trigger, sdram_debug,
// Wishbone interface
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b10)),
wb_we, wb_addr[0], wb_data,
scop_sdram_ack, scop_sdram_stall, scop_sdram_data,
scop_sdram_interrupt);
 
assign scop_c_ack = scop_sdram_ack;
assign scop_c_stall = scop_sdram_stall;
assign scop_c_data = scop_sdram_data;
assign scop_c_interrupt = scop_sdram_interrupt;
`else
assign scop_c_data = 32'h00;
assign scop_c_stall = 1'b0;
assign scop_c_interrupt = 1'b0;
1033,7 → 1162,7
always @(posedge i_clk)
r_scop_c_ack <= (wb_stb)&&(scop_sel)&&(wb_addr[2:1] == 2'b10);
assign scop_c_ack = r_scop_c_ack;
//`endif
`endif
 
//
// SCOPE D
1052,13 → 1181,19
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
: ((wb_addr[2:1]==2'b10)?scop_c_stall
: scop_d_stall))); // Will always be 1'b0;
initial scop_ack = 1'b0;
always @(posedge i_clk)

powered by: WebSVN 2.1.0

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