Commit 2ec40de8 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

started status read infrastucture

parent 10e88af6
Loading
Loading
Loading
Loading
+35 −24
Original line number Diff line number Diff line
@@ -24,14 +24,25 @@ module cmd_mux #(
    parameter AXI_WR_ADDR_BITS=    13,
    parameter CONTROL_ADDR =        'h1000, // AXI write address of control write registers
    parameter CONTROL_ADDR_MASK =   'h1400, // AXI write address of control registers
//    parameter CONTROL_SS_ADDR=      'h0200, // single-cycle command (2-6 cycles decoded by ROM form some address bits)
//    parameter CONTROL_SS_MASK=      'h0200,
    parameter NUM_CYCLES_LOW_BIT=   6 // decode addresses [NUM_CYCLES_LOW_BIT+:4] into command a/d length 
    // now all control addresses may generate busy, but only for command sequencer and multy-byte commands
//    parameter BUSY_WR_ADDR =        'h1800, // AXI write address to generate busy
//    parameter BUSY_WR_ADDR_MASK =   'h1c00 // AXI write address mask to generate busy
    parameter NUM_CYCLES_LOW_BIT=   6, // decode addresses [NUM_CYCLES_LOW_BIT+:4] into command a/d length
    parameter NUM_CYCLES_00 =       9, // single-cycle
    parameter NUM_CYCLES_01 =       2, // 2-cycle
    parameter NUM_CYCLES_02 =       3, // 3-cycle
    parameter NUM_CYCLES_03 =       4, // 4-cycle
    parameter NUM_CYCLES_04 =       5, // 5-cycle
    parameter NUM_CYCLES_05 =       6, // 6-cycle
    parameter NUM_CYCLES_06 =       6, //
    parameter NUM_CYCLES_07 =       6, //
    parameter NUM_CYCLES_08 =       6, //
    parameter NUM_CYCLES_09 =       6, //
    parameter NUM_CYCLES_10 =       6, //
    parameter NUM_CYCLES_11 =       6, //
    parameter NUM_CYCLES_12 =       6, //
    parameter NUM_CYCLES_13 =       6, //
    parameter NUM_CYCLES_14 =       6, //
    parameter NUM_CYCLES_15 =       6 //
) (
    input                         clk,
    input                         axi_clk,
    input                         mclk,
    input                         rst,
    // direct commands from AXI. No wait but for multi-cycle output and command sequencer (having higher priority)
@@ -86,7 +97,7 @@ module cmd_mux #(
    assign seq_length_rom_a=par_ad[NUM_CYCLES_LOW_BIT+:4];
    assign ss= seq_length[3];

    always @ (posedge clk or posedge rst) begin
    always @ (posedge axi_clk or posedge rst) begin
        if (rst)               selected <= 1'b0;
        else if (start_wburst) selected <= selected_w;
        if (rst)               busy_r <= 1'b0;
@@ -97,22 +108,22 @@ module cmd_mux #(
//    always @ (seq_length_rom_a) begin
    always @*
        case (seq_length_rom_a)  // just temporary - fill out later
            4'h00:seq_length<=9; // single-cycle
            4'h01:seq_length<=2; // 2-cycle
            4'h02:seq_length<=3;
            4'h03:seq_length<=4;
            4'h04:seq_length<=5;
            4'h05:seq_length<=6; // 6-cycle (full)
            4'h06:seq_length<=6;
            4'h07:seq_length<=6;
            4'h08:seq_length<=6;
            4'h09:seq_length<=6;
            4'h0a:seq_length<=6;
            4'h0b:seq_length<=6;
            4'h0c:seq_length<=6;
            4'h0d:seq_length<=6;
            4'h0e:seq_length<=6;
            4'h0f:seq_length<=6;
            4'h00:seq_length <= NUM_CYCLES_00;
            4'h01:seq_length <= NUM_CYCLES_01;
            4'h02:seq_length <= NUM_CYCLES_02;
            4'h03:seq_length <= NUM_CYCLES_03;
            4'h04:seq_length <= NUM_CYCLES_04;
            4'h05:seq_length <= NUM_CYCLES_05;
            4'h06:seq_length <= NUM_CYCLES_06;
            4'h07:seq_length <= NUM_CYCLES_07;
            4'h08:seq_length <= NUM_CYCLES_08;
            4'h09:seq_length <= NUM_CYCLES_09;
            4'h0a:seq_length <= NUM_CYCLES_10;
            4'h0b:seq_length <= NUM_CYCLES_11;
            4'h0c:seq_length <= NUM_CYCLES_12;
            4'h0d:seq_length <= NUM_CYCLES_13;
            4'h0e:seq_length <= NUM_CYCLES_14;
            4'h0f:seq_length <= NUM_CYCLES_15;
        endcase
    always @ (posedge rst or posedge mclk) begin
        if (rst) seq_busy_r<=0;
+10 −10
Original line number Diff line number Diff line
@@ -136,8 +136,8 @@ module memctrl16 #(
    inout                        NDQSL, // ~LDQS I/O pad
    output                       SDDMU, // UDM  I/O pad (actually only output)
    inout                        DQSU,  // UDQS I/O pad
    inout                        NDQSU,
    output                       DUMMY_TO_KEEP  // to keep PS7 signals from "optimization"
    inout                        NDQSU //,
//    output                       DUMMY_TO_KEEP  // to keep PS7 signals from "optimization"
//    input                        MEMCLK
);
// TODO: copy from ddrc_test01.v    
+90 −0
Original line number Diff line number Diff line
/*******************************************************************************
 * Module: fifo_1cycle
 * Date:2014-05-20  
 * Author: Andrey Filippov
 * Description: Configurable synchronous FIFO using the same clock for read and write
 * Single clock cycle latency - simple fifo using sync in, async out RAM,
 * no registers on input and output
 * Copyright (c) 2014 Elphel, Inc.
 * fifo_1cycle.v is free software; 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.
 *
 *  fifo_1cycle.v is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *******************************************************************************/
`timescale 1ns/1ps
`define DEBUG_FIFO 1 
module fifo_1cycle
#(
  parameter integer DATA_WIDTH=16,
  parameter integer DATA_DEPTH=4
)
    (
  input                   rst,      // reset, active high
  input                   clk,      // clock - positive edge
  input                   we,       // write enable
  input                   re,       // read enable
  input  [DATA_WIDTH-1:0] data_in,  // input data
  output [DATA_WIDTH-1:0] data_out, // output data
  output reg              nempty,   // FIFO has some data
  output reg              half_full // FIFO half full
`ifdef DEBUG_FIFO
    ,output reg                 under,    // debug outputs - under - attempt to read from empty
    output reg                  over,      // overwritten
    output reg [DATA_DEPTH-1:0] wcount,
    output reg [DATA_DEPTH-1:0] rcount,
    output     [DATA_DEPTH-1:0] num_in_fifo
    
`endif
  );
    localparam integer DATA_2DEPTH=(1<<DATA_DEPTH)-1;
    reg  [DATA_DEPTH-1:0] fill=0; // RAM fill
    reg  [DATA_DEPTH-1:0] ra;
    reg  [DATA_DEPTH-1:0] wa;
    wire [DATA_DEPTH-1:0] next_fill;
    reg  [DATA_WIDTH-1:0] ram [0:DATA_2DEPTH];
    
`ifdef DEBUG_FIFO
    assign num_in_fifo=fill[DATA_DEPTH-1:0];
`endif

    assign next_fill = fill[DATA_DEPTH-1:0]+((we && ~re)?1:((~we && re)?-1:0));
    
    always @ (posedge  clk or posedge  rst) begin
      if   (rst) fill <= 0;
      else fill <= next_fill;
      if (rst)      wa <= 0;
      else if (we) wa <= wa+1;
      if (rst)      ra <=  0;
      else if (re) ra <= ra+1;
      else if (fill==0) ra <= wa; // Just recover from bit errors
      if (rst) nempty <= 0;
      else nempty <= (next_fill!=0);


`ifdef DEBUG_FIFO
      if (rst)     wcount <= 0;
      else if (we) wcount <= wcount + 1;

      if (rst)     rcount <= 0;
      else if (re) rcount <= rcount + 1;
`endif      
    end

    assign data_out=ram[ra]; // async out
    always @ (posedge  clk) begin
      half_full <=(fill & (1<<(DATA_DEPTH-1)))!=0; // MSB == 1
      if (we)  ram[wa]  <= data_in;
`ifdef DEBUG_FIFO
      under <= ~we & re & ~nempty; // underrun error
      over <=  we & ~re & (fill == (1<< (DATA_DEPTH-1)));    // overrun error
`endif      
    end
endmodule
+129 −0
Original line number Diff line number Diff line
/*******************************************************************************
 * Module: status_router2
 * Date:2015-01-13  
 * Author: andrey     
 * Description: 2:1 status data router/mux
 *
 * Copyright (c) 2015 <set up in Preferences-Verilog/VHDL Editor-Templates> .
 * status_router2.v is free software; 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.
 *
 *  status_router2.v is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/> .
 *******************************************************************************/
 //TODO: make a 4-input mux too?
`timescale 1ns/1ps
`define DEBUG_FIFO 1
module  status_router2 (
    input        rst,
    input        clk,
    // 2 input channels 
    input [7:0]  db_in0,
    input        rq_in0,
    output       start_in0, // only for the first cycle, combinatorial
    input [7:0]  db_in1,
    input        rq_in1,
    output       start_in1, // only for the first cycle, combinatorial
    // output (multiplexed) channel
    output [7:0] db_out,
    output       rq_out,
    input        start_out  // only for the first cycle, combinatorial
);
    wire           [1:0] rq_in={rq_in1,rq_in0};
    wire           [1:0] start_rcv;
    reg            [1:0] rcv_rest_r; // receiving remaining (after first) bytes
    wire           [1:0] fifo_half_full;
    
    assign         start_in0=start_rcv[0];
    assign         start_in1=start_rcv[1];

    assign start_rcv=~fifo_half_full & ~rcv_rest_r & rq_in;
    wire   [7:0] fifo0_out;
    wire   [7:0] fifo1_out;
    wire   [1:0] fifo_last_byte;
    wire   [1:0] fifo_nempty;
    wire   [1:0] fifo_re;
    reg          next_chn;
    reg          current_chn_r;
    reg          snd_rest_r;
    wire         snd_pre_start; 
    wire         snd_last_byte;
    wire         chn_sel_w;
    wire         early_chn;

    assign       chn_sel_w=(&fifo_nempty)?next_chn:&fifo_nempty[1];
    assign       fifo_re=start_out?{chn_sel_w,~chn_sel_w}:(snd_rest_r?{current_chn_r,~current_chn_r}:2'b0);
    
    assign snd_last_byte=current_chn_r?fifo_last_byte[1]:fifo_last_byte[0];
    assign snd_pre_start=|fifo_nempty && (!snd_rest_r || snd_last_byte);
    assign rq_out=(snd_rest_r && !snd_last_byte) || |fifo_nempty;
    assign early_chn= (snd_rest_r & ~snd_last_byte)?current_chn_r:chn_sel_w;
    assign db_out=early_chn?fifo1_out:fifo0_out;
    always @ (posedge rst or posedge clk) begin
        if (rst) rcv_rest_r<= 0;
        else rcv_rest_r <= (rcv_rest_r & rq_in) | start_rcv;
    
        if (rst) next_chn<= 0;
        else if (|fifo_re) next_chn <= fifo_re[0];
        if (rst) current_chn_r<= 0;
        else if (snd_pre_start) current_chn_r <= chn_sel_w;

        if (rst) snd_rest_r<= 0;
        else snd_rest_r <= (snd_rest_r & ~snd_last_byte) | start_out;
    end
    
/* fifo_same_clock has currently latency of 2 cycles, use smth. faster here? - fifo_1cycle (but it has unregistered data output) */
    fifo_1cycle #(
        .DATA_WIDTH(9),
        .DATA_DEPTH(4) // 16
    ) fifo_in0_i (
        .rst       (rst), // input
        .clk       (clk), // input
        .we        (start_rcv[0] || rcv_rest_r[0]), // input
        .re        (fifo_re[0]), // input
        .data_in   ({rcv_rest_r[0] & ~rq_in[0], db_in0}), // input[8:0] MSB marks last byte
        .data_out  ({fifo_last_byte[0],fifo0_out}), // output[8:0]
        .nempty    (fifo_nempty[0]), // output
        .half_full (fifo_half_full[0]) // output reg 
`ifdef DEBUG_FIFO
        ,.under(), // output reg 
        .over(), // output reg 
        .wcount(), // output[3:0] reg 
        .rcount(), // output[3:0] reg 
        .num_in_fifo() // output[3:0]
`endif         
    );

    fifo_1cycle #(
        .DATA_WIDTH(9),
        .DATA_DEPTH(4) // 16
    ) fifo_in1_i (
        .rst       (rst), // input
        .clk       (clk), // input
        .we        (start_rcv[1] || rcv_rest_r[1]), // input
        .re        (fifo_re[1]), // input
        .data_in   ({rcv_rest_r[1] & ~rq_in[1], db_in1}), // input[8:0] MSB marks last byte
        .data_out  ({fifo_last_byte[1],fifo1_out}), // output[8:0]
        .nempty    (fifo_nempty[1]), // output
        .half_full (fifo_half_full[1]) // output reg 
`ifdef DEBUG_FIFO
        ,.under(), // output reg 
        .over(), // output reg 
        .wcount(), // output[3:0] reg 
        .rcount(), // output[3:0] reg 
        .num_in_fifo() // output[3:0]
`endif         
    );
      
// one car per green (round robin priority)
// start sending out with  with one cycle latency - now 2 cycles because of the FIFO

endmodule

x393.v

0 → 100644
+1348 −0

File added.

Preview size limit exceeded, changes collapsed.