Commit 0cfebd24 authored by Andrey Filippov's avatar Andrey Filippov

More editing, trying to run Xilinx tools

parent 210ed954
...@@ -62,77 +62,77 @@ ...@@ -62,77 +62,77 @@
<link> <link>
<name>vivado_logs/VivadoBitstream.log</name> <name>vivado_logs/VivadoBitstream.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoBitstream-20150720133322322.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoBitstream-20150722003723406.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOpt.log</name> <name>vivado_logs/VivadoOpt.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOpt-20150720133322322.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoOpt-20150722003207037.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOptPhys.log</name> <name>vivado_logs/VivadoOptPhys.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPhys-20150720133322322.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoOptPhys-20150722003723406.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoOptPower.log</name> <name>vivado_logs/VivadoOptPower.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoOptPower-20150720133322322.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoOptPower-20150722003207037.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoPlace.log</name> <name>vivado_logs/VivadoPlace.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoPlace-20150720133322322.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoPlace-20150722003207037.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoRoute.log</name> <name>vivado_logs/VivadoRoute.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoRoute-20150720133322322.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoRoute-20150722003723406.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoSynthesis.log</name> <name>vivado_logs/VivadoSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoSynthesis-20150720130350146.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoSynthesis-20150722002329036.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name> <name>vivado_logs/VivadoTimimgSummaryReportImplemented.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportImplemented-20150720133322322.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportImplemented-20150722003723406.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name> <name>vivado_logs/VivadoTimimgSummaryReportSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportSynthesis-20150720130350146.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoTimimgSummaryReportSynthesis-20150722002329036.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name> <name>vivado_logs/VivadoTimingReportImplemented.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimingReportImplemented-20150720133322322.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoTimingReportImplemented-20150722003723406.log</location>
</link> </link>
<link> <link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name> <name>vivado_logs/VivadoTimingReportSynthesis.log</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimingReportSynthesis-20150720130350146.log</location> <location>/home/andrey/git/x393/vivado_logs/VivadoTimingReportSynthesis-20150722002329036.log</location>
</link> </link>
<link> <link>
<name>vivado_state/x393-opt-phys.dcp</name> <name>vivado_state/x393-opt-phys.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_state/x393-opt-phys-20150720133322322.dcp</location> <location>/home/andrey/git/x393/vivado_state/x393-opt-phys-20150722003723406.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393-place.dcp</name> <name>vivado_state/x393-place.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_state/x393-place-20150720133322322.dcp</location> <location>/home/andrey/git/x393/vivado_state/x393-place-20150722003207037.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393-route.dcp</name> <name>vivado_state/x393-route.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_state/x393-route-20150720133322322.dcp</location> <location>/home/andrey/git/x393/vivado_state/x393-route-20150722003723406.dcp</location>
</link> </link>
<link> <link>
<name>vivado_state/x393-synth.dcp</name> <name>vivado_state/x393-synth.dcp</name>
<type>1</type> <type>1</type>
<location>/home/andrey/git/x393/vivado_state/x393-synth-20150720130350146.dcp</location> <location>/home/andrey/git/x393/vivado_state/x393-synth-20150722002329036.dcp</location>
</link> </link>
</linkedResources> </linkedResources>
</projectDescription> </projectDescription>
...@@ -4,6 +4,6 @@ VivadoSynthesis_115_flatten_hierarchy=none ...@@ -4,6 +4,6 @@ VivadoSynthesis_115_flatten_hierarchy=none
VivadoSynthesis_127_verbose=true VivadoSynthesis_127_verbose=true
VivadoSynthesis_81_parser_mode=1 VivadoSynthesis_81_parser_mode=1
VivadoSynthesis_93_OtherProblems=Netlist 29-345<-@\#\#@->Board 49-26<-@\#\#@-> VivadoSynthesis_93_OtherProblems=Netlist 29-345<-@\#\#@->Board 49-26<-@\#\#@->
VivadoSynthesis_95_ShowInfo=true VivadoSynthesis_95_ShowInfo=false
com.elphel.store.context.VivadoSynthesis=VivadoSynthesis_102_ConstraintsFiles<-@\#\#@->VivadoSynthesis_95_ShowInfo<-@\#\#@->VivadoSynthesis_115_flatten_hierarchy<-@\#\#@->VivadoSynthesis_101_MaxMsg<-@\#\#@->VivadoSynthesis_127_verbose<-@\#\#@->VivadoSynthesis_93_OtherProblems<-@\#\#@->VivadoSynthesis_81_parser_mode<-@\#\#@-> com.elphel.store.context.VivadoSynthesis=VivadoSynthesis_102_ConstraintsFiles<-@\#\#@->VivadoSynthesis_95_ShowInfo<-@\#\#@->VivadoSynthesis_115_flatten_hierarchy<-@\#\#@->VivadoSynthesis_101_MaxMsg<-@\#\#@->VivadoSynthesis_127_verbose<-@\#\#@->VivadoSynthesis_93_OtherProblems<-@\#\#@->VivadoSynthesis_81_parser_mode<-@\#\#@->
eclipse.preferences.version=1 eclipse.preferences.version=1
...@@ -455,8 +455,8 @@ module cmprs_afi_mux#( ...@@ -455,8 +455,8 @@ module cmprs_afi_mux#(
.chunk_ptr_ra (chunk_ptr_ra), // output[3:0] reg .chunk_ptr_ra (chunk_ptr_ra), // output[3:0] reg
.chunk_ptr_rd (chunk_ptr_rd[CMPRS_AFIMUX_WIDTH-1:0]) // input[25:0] .chunk_ptr_rd (chunk_ptr_rd[CMPRS_AFIMUX_WIDTH-1:0]) // input[25:0]
); );
pulse_cross_clock sa_len_we_i (.rst(rst), .src_clk(mclk), .dst_clk(hclk), .in_pulse(cmd_we_sa_len_w), .out_pulse(sa_len_we),.busy()); pulse_cross_clock sa_len_we_i (.rst(mrst), .src_clk(mclk), .dst_clk(hclk), .in_pulse(cmd_we_sa_len_w), .out_pulse(sa_len_we),.busy());
pulse_cross_clock en_we_i (.rst(rst), .src_clk(mclk), .dst_clk(hclk), .in_pulse(cmd_we_en_w), .out_pulse(en_we), .busy()); pulse_cross_clock en_we_i (.rst(mrst), .src_clk(mclk), .dst_clk(hclk), .in_pulse(cmd_we_en_w), .out_pulse(en_we), .busy());
pulse_cross_clock en_rst_i (.rst(rst), .src_clk(mclk), .dst_clk(hclk), .in_pulse(cmd_we_rst_w), .out_pulse(en_rst),.busy()); pulse_cross_clock en_rst_i (.rst(mrst), .src_clk(mclk), .dst_clk(hclk), .in_pulse(cmd_we_rst_w), .out_pulse(en_rst),.busy());
endmodule endmodule
...@@ -421,7 +421,6 @@ module histogram_saxi#( ...@@ -421,7 +421,6 @@ module histogram_saxi#(
) fifo_same_clock_i ( ) fifo_same_clock_i (
.rst (1'b0), // input .rst (1'b0), // input
.clk (aclk), // input .clk (aclk), // input
.sync_rst (arst), // input
.sync_rst (!en_aclk), // input .sync_rst (!en_aclk), // input
.we (buf_re[2]), // input .we (buf_re[2]), // input
.re (fifo_re), // input .re (fifo_re), // input
......
/*******************************************************************************
* Module: color_proc393
* Date:2015-06-10
* Author: Andrey Filippov
* Description: Color processor for JPEG 4:2:0/JP4
* Updating from the earlier 2002-2010 version
*
* Copyright (c) 2002-2015 Elphel, Inc.
* color_proc393.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.
*
* color_proc393.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_COMPRESSOR
module color_proc393 (
input clk, // pixel clock (1/2 system clock - 80MHz)
input en, // Enable (0 will reset states)
input en_sdc, // enable subtracting of DC component
input go, // pulse to star/restart (needed for each frame, repeat generated by the caller)
// TODO: Remove
input [25:0] nblocks, // ***** was [17:0] number of 16x16 blocks to read (valid @ "go" pulse)
// NEW: Now number of SDRAM blobks (tiles) is not equal to number of macroblocks
input [12:0] n_blocks_in_row, // number of macroblocks in a macroblock row
input [12:0] n_block_rows, // number of macroblock rows in a frame
// input reset_sdram_page, // SDRAM buffer page may be reset (normally just increments for each new tile
// end of NEW
output eot, // single-cycle end of transfer pulse
input [ 9:0] m_cb, // [9:0] scale for CB - default 0.564 (10'h90)
input [ 9:0] m_cr, // [9:0] scale for CB - default 0.713 (10'hb6)
input memWasInit, // memory channel2 was just initialized - reset page address (at posedge clk)
input [ 7:0] di, // [7:0]
output [11:0] sdram_a, // ***** was [10:0] (MSB - SDRAM buffer page number)
input sdram_rdy, // SDRAM buffer ready
output sdram_next, // request to read a page to SDRAM buffer
output inc_sdrama, // enable read sdram buffer
output inc_sdrama_d,// ***** NEW regen sdram buffer (delay by 1 clock
input noMoreData, // used as alternative to end frame input (possibly broken frame)
output dv_raw, // data valid for di (for testing to bypass color conversion - use di[7:0])
input ignore_color, //zero Cb/Cr components
input four_blocks, // use only 4 blocks for the output, not 6
input jp4_dc_improved, // in JP4 mode, compare DC coefficients to the same color ones
input [ 1:0] tile_margin, // margins around 16x16 tiles (0/1/2)
input [ 2:0] tile_shift, // tile shift from top left corner
input [ 2:0] converter_type, // 0 - color18, 1 - color20, 2 - mono, 3 - jp4, 4 - jp4-diff
input scale_diff, // divide differences by 2 (to fit in 8-bit range)
input hdr, // second green absolute, not difference
output [ 9:0] do, // [9:0] data out (4:2:0) (signed, average=0)
output [ 8:0] avr, // [8:0] DC (average value) - RAM output, no register. For Y components 9'h080..9'h07f, for C - 9'h100..9'h0ff!
output dv, // out data valid (will go high for at least 64 cycles)
output ds, // single-cycle mark of the first_r pixel in a 64 (8x8) - pixel block
output [ 2:0] tn, // [2:0] tile number 0..3 - Y, 4 - Cb, 5 - Cr (valid with start)
output first, // sending first_r MCU (valid @ ds)
output last, // sending last_r MCU (valid @ ds)
output [ 7:0] n000, // [7:0] number of zero pixels (255 if 256)
output [ 7:0] n255, // [7:0] number of 0xff pixels (255 if 256)
input [ 1:0] bayer_phase, //[1:0]) bayer color filter phase 0:(GR/BG), 1:(RG/GB), 2: (BG/GR), 3: (GB/RG)
// below signals valid at ds ( 1 later than tn, first_r, last_r)
output [2:0] component_num, //[2:0] - component number (YCbCr: 0 - Y, 1 - Cb, 2 - Cr, JP4: 0-1-2-3 in sequence (depends on shift) 4 - don't use
output component_color, // use color quantization table (YCbCR, jp4diff)
output component_first, // first_r this component in a frame (DC absolute, otherwise - difference to previous)
output component_lastinmb // last_r component in a macroblock;
`ifdef DEBUG_COMPRESSOR
,output bcntrIsZero
,output [25:0] bcntr
`endif
);
wire [8:0] y_out; // data from buffer
wire [8:0] c_out; // data from buffer
reg [1:0] wpage; // page (0/1) where data is being written to (both Y and CbCr)
reg [1:0] rpage; // page (0/1) from where data is sent out ( both Y and CbCr)
reg sdram_next_r;
reg [25:0] bcntr_r; // down counter of blocks left
reg bcntrIsZero_r; // one cycle of bcntr_r[]==0
reg eot_r;
reg ccv_start_en; //
reg ccv_out_start,ccv_out_start_d; // start output of YCbCr from buffers
reg [8:0] raddr; // output address of buffer memories (MSB selects Y(0)/CbCr(1))
reg raddr8_d; // raddr[8] delayed by 1 clock to control bram regen
reg dv0; // "dv0" - one cycle ahead of "dv" to compensate for "do_r" register latency
reg ds0; // "ds0" - one cycle ahead of "ds" to compensate for "do_r" register latency
// reg [8:0] do_r;
// reg [8:0] pre_do;
reg [9:0] do_r;
reg [9:0] pre_do;
reg [1:0] pre_dv, pre_ds;
reg dv_raw_r;
// 16x8 dual port RAM
reg buf_sel;
reg willbe_first;
reg first_r,first0;
reg last_r,last0;
reg [4:0] preline; // number of line in a tile, down counter (0x13->0, 0x11->0, 0x0f->0), 1 cycles ahead of data from SDRAM
reg [4:0] prepix; // number of pixel in a line in a tile, down counter (0x13->0, 0x11->0, 0x0f->0)
reg [1:0] sdram_a9_page;
reg [8:0] sdram_a9;
reg [8:0] seq_cntr; // master
wire [4:0] tile_size;
wire [8:0] macroblock_period_minus1;
wire all_ready;
reg preline_was_0;
reg pre_start_of_line;
reg pre_first_pixel;
reg [8:0] sdrama_top_left; // address of top left corner to be processed
reg [2:0] sdrama_line_inc; // increment amount when proceeding to next tile line
reg [1:0] inc_sdrama_r;
reg last_from_sdram; // reading last_r byte from SDRAM
reg first_pixel; // reading first_r pixel to color converter (di will be available next cycle)
reg tim2next;
reg [8:0] y_in, c_in;
reg [7:0] yaddrw, caddrw;
reg ywe, cwe;
reg color_enable, pre_color_enable;// prevent random colors in monochrome/JP46 modes (pre_* - sync input)
reg cs_pre_first_out; // clear color accumulators
wire [7:0] conv18_y_in, conv20_y_in, mono_y_in, jp4_y_in;
wire [8:0] jp4diff_y_in, conv18_c_in, conv20_c_in;
wire [7:0] conv18_yaddrw, conv20_yaddrw, mono_yaddrw, jp4_yaddrw, jp4diff_yaddrw;
wire [6:0] conv18_caddrw, conv20_caddrw;
wire conv18_ywe, conv18_cwe, conv20_ywe, conv20_cwe, mono_ywe, jp4_ywe, jp4diff_ywe;
wire conv18_pre_first_out, conv20_pre_first_out, mono_pre_first_out, jp4_pre_first_out, jp4diff_pre_first_out;
reg [4:0] en_converters;
reg [2:0] converter_type_r;
reg ignore_color_r;
reg jp4_dc_improved_r;
reg four_blocks_r;
reg scale_diff_r;
reg hdr_r;
reg [1:0] tile_margin_r;
// reg [2:0] tile_shift_r;
reg [1:0] bayer_phase_r;
reg [3:0] bayer_phase_onehot;
reg raddr_lastInBlock;
reg raddr_updateBlock; // first_r in block, after last_r also. Should be when *_r match the currently selected converter for the macroblock
// component_num,component_color,component_first for different converters vs tn (1 bit per tn (0..5)
reg component_lastinmb_r; // last_r component in a macroblock;
reg [5:0] component_numsL, component_numsLS; // component_num[0] vs tn
reg [5:0] component_numsM, component_numsMS; // component_num[1] vs tn
reg [5:0] component_numsH, component_numsHS; // component_num[2] vs tn
reg [5:0] component_colors, component_colorsS; // use color quantization table (YCbCR, jp4diff)
reg [5:0] component_firsts, component_firstsS; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
reg eof_rq; // request to end frame if there will be no more data
`ifdef DEBUG_COMPRESSOR
assign bcntr = bcntr_r;
assign bcntrIsZero= bcntrIsZero_r;
`endif
assign component_lastinmb=component_lastinmb_r;
assign sdram_a = {sdram_a9_page[1:0],sdram_a9[8:0]};
assign tn[2:0] = raddr[8:6];
assign sdram_next = sdram_next_r;
assign inc_sdrama = inc_sdrama_r[0];
assign inc_sdrama_d = inc_sdrama_r[1];
assign eot = eot_r;
assign first = first_r;
assign last = last_r;
assign dv_raw = dv_raw_r;
assign do = do_r;
assign dv = pre_dv[1];
assign ds = pre_ds[1];
assign component_num[2:0]= {component_numsH[0],component_numsM[0],component_numsL[0]};
assign component_color = component_colors[0];
assign component_first = component_firsts[0];
assign all_ready = sdram_rdy && ccv_start_en;
assign macroblock_period_minus1[8:0] = four_blocks?(tile_margin[1]?9'h18f:(tile_margin[0]?9'h143:9'h0ff)):(tile_margin[1]?9'h18f:9'h17f);
assign tile_size[4:0] = tile_margin[1]?5'h13:(tile_margin[0]?5'h11:5'h0f);
always @ (posedge clk) begin
if (!en) seq_cntr[8:0] <=9'h0;
else if (seq_cntr[8:0]!=0) seq_cntr[8:0] <= seq_cntr[8:0] -1;
else if (all_ready) seq_cntr[8:0] <= macroblock_period_minus1;
preline_was_0 <= (preline[4:0]==5'h0);
if ((seq_cntr[8:0]==0) || ((prepix[4:0]==0) && !preline_was_0) ) prepix[4:0] <= tile_size[4:0];
else if (prepix[4:0]!=0) prepix[4:0] <= prepix[4:0] - 1;
if (seq_cntr[8:0]==0) preline[4:0] <= tile_size[4:0];
else if ((prepix[4:0]==0) && !preline_was_0) preline[4:0] <= preline[4:0] - 1;
pre_start_of_line <= ((seq_cntr[8:0]==0) || ((prepix[4:0]==0) && !preline_was_0) );
pre_first_pixel <= en && (seq_cntr[8:0]==9'h0) && all_ready;
case (tile_shift[2:0])
3'h0: sdrama_top_left[8:0] <= 9'h0;
3'h1: sdrama_top_left[8:0] <= 9'h15;
3'h2: sdrama_top_left[8:0] <= 9'h2a;
3'h3: sdrama_top_left[8:0] <= 9'h3f;
3'h4: sdrama_top_left[8:0] <= 9'h54;
endcase
case (tile_margin[1:0])
2'h0: sdrama_line_inc[2:0] <= 3'h5;
2'h1: sdrama_line_inc[2:0] <= 3'h3;
2'h2: sdrama_line_inc[2:0] <= 3'h1;
endcase
first_pixel <= pre_first_pixel;
last_from_sdram <= en & preline_was_0 && (prepix[4:0]==0);
inc_sdrama_r <= en & (pre_first_pixel || (inc_sdrama_r && !last_from_sdram ));
if (pre_first_pixel) sdram_a9[8:0] <= sdrama_top_left[8:0];
else if (inc_sdrama_r) sdram_a9[8:0] <= sdram_a9[8:0] + (pre_start_of_line ? sdrama_line_inc[2:0] : 3'h1);
if (!en || memWasInit) sdram_a9_page[1:0] <= 2'h0;
else if (last_from_sdram && inc_sdrama_r) sdram_a9_page[1:0] <= sdram_a9_page[1:0]+1;
// wpage[1:0] valid with ywe
if (cs_pre_first_out) wpage[1:0] <= sdram_a9_page[1:0]; // copy page from SDRAM buffer
// register control modes to be valid while overlapping
if (pre_first_pixel) begin
converter_type_r [2:0] <= converter_type[2:0];
ignore_color_r <= ignore_color;
jp4_dc_improved_r <= jp4_dc_improved;
four_blocks_r <= four_blocks;
scale_diff_r <= scale_diff;
hdr_r <= hdr;
tile_margin_r[1:0] <= tile_margin[1:0];
bayer_phase_r[1:0] <= bayer_phase[1:0];
bayer_phase_onehot[3:0]<={(bayer_phase[1:0]==2'h3)?1'b1:1'b0,
(bayer_phase[1:0]==2'h2)?1'b1:1'b0,
(bayer_phase[1:0]==2'h1)?1'b1:1'b0,
(bayer_phase[1:0]==2'h0)?1'b1:1'b0};
end
if (!en) en_converters[4:0] <= 0;
else if (pre_first_pixel)
en_converters[4:0]<= {(converter_type[2:0]==3'h4)?1'b1:1'b0,
(converter_type[2:0]==3'h3)?1'b1:1'b0,
(converter_type[2:0]==3'h2)?1'b1:1'b0,
(converter_type[2:0]==3'h1)?1'b1:1'b0,
(converter_type[2:0]==3'h0)?1'b1:1'b0};
end
// new
//cs_pre_first_out
reg [3:0] accYen;
reg [1:0] accCen; // individual accumulator enable (includes clearing)
reg [3:0] accYfirst;
reg [1:0] accCfirst; // add to zero, instead of to acc @ acc*en
reg [8:0] preAccY, preAccC; // registered data from color converters, matching acc selection latency
reg [14:0] accY0,accY1,accY2,accY3,accC0,accC1;
reg cs_first_out;
reg [5:0] accCntrY0,accCntrY1,accCntrY2,accCntrY3,accCntrC0,accCntrC1;
wire [3:0] pre_accYdone;
wire [1:0] pre_accCdone; // need to make sure that pre_accCdone do_r not happen with pre_accYdone
reg [3:0] accYrun;
reg [1:0] accCrun;
reg [3:0] accYdone;
reg accYdoneAny;
reg [1:0] avrY_wa, pre_avrY_wa;
reg avrC_wa, pre_avrC_wa;
reg avrPage_wa, pre_avrPage_wa;
reg avr_we;
reg [8:0] avermem[0:15];
wire [3:0] avr_wa= {avrPage_wa,accYdoneAny?{1'b0,avrY_wa[1:0]}:{2'b10,avrC_wa}};
reg [3:0] avr_ra; // read address
wire [8:0] avrY_di= avrY_wa[1] ? (avrY_wa[0]?accY3[14:6]:accY2[14:6]):(avrY_wa[0]?accY1[14:6]:accY0[14:6]);
wire [8:0] avrC_di= avrC_wa ?accC1[14:6]:accC0[14:6];
assign avr = avermem[avr_ra[3:0]];
assign pre_accYdone[3:0] = {(accCntrY3[5:0]==6'h3e)?1'b1:1'b0,
(accCntrY2[5:0]==6'h3e)?1'b1:1'b0,
(accCntrY1[5:0]==6'h3e)?1'b1:1'b0,
(accCntrY0[5:0]==6'h3e)?1'b1:1'b0} & accYen[3:0];
assign pre_accCdone[1:0] = {(accCntrC1[5:0]==6'h3e)?1'b1:1'b0,
(accCntrC0[5:0]==6'h3e)?1'b1:1'b0} & accCen[1:0];
always @ (posedge clk) begin
cs_first_out<=cs_pre_first_out;
if (ywe) preAccY[8:0] <= y_in[8:0];
if (cwe) preAccC[8:0] <= c_in[8:0];
accYen[3:0] <= {4{en & ywe}} & {yaddrw[7] & yaddrw[6],
yaddrw[7] & ~yaddrw[6],
~yaddrw[7] & yaddrw[6],
~yaddrw[7] & ~yaddrw[6]};
accCen[1:0] <= {2{en & cwe}} & { caddrw[6],
~caddrw[6]};
accYfirst[3:0] <= {4{cs_first_out}} | (accYfirst[3:0] & ~accYen[3:0]);
accCfirst[1:0] <= {2{cs_first_out}} | (accCfirst[1:0] & ~accCen[1:0]);
if (accYen[0]) accY0[14:0]<= (accYfirst[0]?15'h0:accY0[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accYen[1]) accY1[14:0]<= (accYfirst[1]?15'h0:accY1[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accYen[2]) accY2[14:0]<= (accYfirst[2]?15'h0:accY2[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accYen[3]) accY3[14:0]<= (accYfirst[3]?15'h0:accY3[14:0]) + {{6{preAccY[8]}},preAccY[8:0]};
if (accCen[0]) accC0[14:0]<= (accCfirst[0]?15'h0:accC0[14:0]) + {{6{preAccC[8]}},preAccC[8:0]};
if (accCen[1]) accC1[14:0]<= (accCfirst[1]?15'h0:accC1[14:0]) + {{6{preAccC[8]}},preAccC[8:0]};
if (!en) accCntrY0[5:0]<= 6'h0; else if (accYen[0]) accCntrY0[5:0]<= (accYfirst[0]?6'h0:(accCntrY0[5:0]+1));
if (!en) accCntrY1[5:0]<= 6'h0; else if (accYen[1]) accCntrY1[5:0]<= (accYfirst[1]?6'h0:(accCntrY1[5:0]+1));
if (!en) accCntrY2[5:0]<= 6'h0; else if (accYen[2]) accCntrY2[5:0]<= (accYfirst[2]?6'h0:(accCntrY2[5:0]+1));
if (!en) accCntrY3[5:0]<= 6'h0; else if (accYen[3]) accCntrY3[5:0]<= (accYfirst[3]?6'h0:(accCntrY3[5:0]+1));
if (!en) accCntrC0[5:0]<= 6'h0; else if (accCen[0]) accCntrC0[5:0]<= (accCfirst[0]?6'h0:(accCntrC0[5:0]+1));
if (!en) accCntrC1[5:0]<= 6'h0; else if (accCen[1]) accCntrC1[5:0]<= (accCfirst[1]?6'h0:(accCntrC1[5:0]+1));
accYrun[3:0] <= {4{en}} & ((accYfirst[3:0] & accYen[3:0]) | (accYrun[3:0] & ~pre_accYdone[3:0]));
accCrun[1:0] <= {2{en}} & ((accCfirst[1:0] & accCen[1:0]) | (accCrun[1:0] & ~pre_accCdone[1:0]));
accYdone[3:0] <= pre_accYdone[3:0] & accYrun[3:0];
accYdoneAny <= |(pre_accYdone[3:0] & accYrun[3:0]);
avr_we <= |(pre_accYdone[3:0] & accYrun[3:0]) || |(pre_accCdone[1:0] & accCrun[1:0]);
pre_avrY_wa[1:0] <= yaddrw[7:6];
avrY_wa[1:0] <= pre_avrY_wa[1:0];
pre_avrC_wa <= caddrw[ 6];
avrC_wa <= pre_avrC_wa;
pre_avrPage_wa <= wpage[0];
avrPage_wa <= pre_avrPage_wa;
if (avr_we) avermem[avr_wa[3:0]] <= en_sdc?(accYdoneAny?avrY_di[8:0]:avrC_di[8:0]):9'h0;
avr_ra[3:0] <= {rpage[0],raddr[8:6]};
raddr8_d <= raddr[8];
end
reg transfer_ended=0; /// there was already EOT pulse for the current frame
always @ (posedge clk) begin
transfer_ended <= bcntrIsZero_r && (transfer_ended || eot_r);
/*+*/ tim2next <= (seq_cntr[8:0]=='h10); // rather arbitrary number - sdram buffer should in no case be actually overwritten before data read out
// it may depend on relation between SDRAM clk frequency (75MHz) and this clk (variable? 30MHz)
eof_rq <= (tim2next && !bcntrIsZero_r) || (eof_rq && !(inc_sdrama_r || transfer_ended));
ccv_start_en <= en && !eot_r && (ccv_start_en || go); //FIXME: Still uncaught problem: SDRAM ready occurs before go_single!
bcntrIsZero_r <= (bcntr_r==0);
sdram_next_r <= tim2next && ~sdram_next_r;
eot_r <= !transfer_ended && !eot_r && bcntrIsZero_r && (tim2next || (eof_rq && noMoreData));
if (go) bcntr_r <= nblocks;
else if (noMoreData) bcntr_r <= 0;
else if (sdram_next_r && !bcntrIsZero_r) bcntr_r <= bcntr_r-1;
if (ccv_out_start) rpage[1:0] <=wpage[1:0];
if (ccv_out_start) color_enable <= pre_color_enable;
ccv_out_start_d <= ccv_out_start;
raddr_lastInBlock <= en && (raddr[5:0]==6'h3e);
raddr_updateBlock <= raddr_lastInBlock || ccv_out_start;
if (ccv_out_start || !en) raddr[8:0] <= {!en,!en,7'h0}; // 9'h180/9'h000;
else if (!raddr[8] || (!four_blocks_r && !raddr[7])) raddr[8:0] <= raddr[8:0]+1; // for 4 blocks - count for 0,1; 6 blocks - 0,1,2
dv0 <= en && raddr_updateBlock?(!raddr[8] || (!four_blocks_r && !raddr[7])):dv0;
ds0 <= raddr_updateBlock && (!raddr[8] || (!four_blocks_r && !raddr[7]));
buf_sel <= raddr[8];
pre_do[9:0] <= buf_sel?(color_enable?({c_out[8],c_out[8:0]}-{avr[8],avr[8:0]}):10'b0):({y_out[8],y_out[8:0]}-{avr[8],avr[8:0]});
//color_enable
do_r[9:0] <= pre_do[9:0];
dv_raw_r <= inc_sdrama_r && en;
if (go) willbe_first <= 1'b1;
else if (first_pixel) willbe_first <= 1'b0;
if (first_pixel) begin
first0 <= willbe_first;
last0 <= (bcntr_r[17:0]==18'b0);
end
if (ccv_out_start) begin
first_r <= first0;
last_r <= last0;
end
// 8x8 memory to hold average values
pre_dv[1:0] <= {pre_dv[0],dv0};
pre_ds[1:0] <= {pre_ds[0],ds0};
// Shift registers - generating block attributes to be used later in compressor
if (raddr_updateBlock) begin
if (ccv_out_start_d) begin
component_numsL[5:0] <= component_numsLS[5:0];
component_numsM[5:0] <= component_numsMS[5:0];
component_numsH[5:0] <= component_numsHS[5:0];
component_colors[5:0] <= component_colorsS[5:0];
component_firsts[5:0] <= first0? component_firstsS[5:0]:6'h0; // here we may use first0 that is one cycle earlier and ends much earlier
end else begin
component_numsL[5:0] <= {1'b0,component_numsL[5:1]};
component_numsM[5:0] <= {1'b0,component_numsM[5:1]};
component_numsH[5:0] <= {1'b0,component_numsH[5:1]};
component_colors[5:0] <= {1'b0,component_colors[5:1]};
component_firsts[5:0] <= {1'b0,component_firsts[5:1]};
end
end
component_lastinmb_r <= tn[0] && (four_blocks_r? tn[1] : tn[2]); // last_r component in a macroblock;
end
// average for each block should be calculated before the data goes to output output
always @ (posedge clk) case (converter_type_r[2:0])
3'h0:begin //color 18
cs_pre_first_out <= conv18_pre_first_out;
y_in[8:0] <= {conv18_y_in[7],conv18_y_in[7:0]};
ywe <= conv18_ywe;
yaddrw[7:0] <= {conv18_yaddrw[7],conv18_yaddrw[3],conv18_yaddrw[6:4],conv18_yaddrw[2:0]};
c_in[8:0] <= {conv18_c_in[8:0]};
cwe <= conv18_cwe;
pre_color_enable <= 1'b1;
caddrw[7:0] <= {1'b0,conv18_caddrw[6:0]};
ccv_out_start <= (conv18_yaddrw[7:0]==8'hc5); //TODO: adjust to minimal latency?
component_numsLS <= 6'h10; // component_num [0]
component_numsMS <= 6'h20; // component_num [1]
component_numsHS <= 6'h00; // component_num [2]
component_colorsS <= 6'h30; // use color quantization table (YCbCR, jp4diff)
component_firstsS <= 6'h31; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
end
3'h1:begin //color 20
cs_pre_first_out <= conv20_pre_first_out;
y_in[8:0] <= {conv20_y_in[7],conv20_y_in[7:0]};
ywe <= conv20_ywe;
yaddrw[7:0] <= {conv20_yaddrw[7],conv20_yaddrw[3],conv20_yaddrw[6:4],conv20_yaddrw[2:0]};
c_in[8:0] <= {conv20_c_in[8:0]};
cwe <= conv20_cwe;
pre_color_enable <= 1'b1;
caddrw[7:0] <= {1'b0,conv20_caddrw[6:0]};
ccv_out_start <= (conv20_yaddrw[7:0]==8'hc5); //TODO: adjust to minimal latency?
component_numsLS <= 6'h10; // component_num [0]
component_numsMS <= 6'h20; // component_num [1]
component_numsHS <= 6'h3f; // component_num [2]
component_colorsS <= 6'h30; // use color quantization table (YCbCR, jp4diff)
component_firstsS <= 6'h31; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
end
3'h2:begin //mono
cs_pre_first_out <= mono_pre_first_out;
y_in[8:0] <= {mono_y_in[7],mono_y_in[7:0]};
ywe <= mono_ywe;
yaddrw[7:0] <= {mono_yaddrw[7],mono_yaddrw[3],mono_yaddrw[6:4],mono_yaddrw[2:0]};
c_in[8:0] <= 9'h0;
cwe <= 1'b0;
pre_color_enable <= 1'b0;
caddrw[7:0] <= 8'h0;
ccv_out_start <= accYdone[0];
component_numsLS <= 6'h10; // component_num [0]
component_numsMS <= 6'h20; // component_num [1]
component_numsHS <= 6'h30; // component_num [2]
component_colorsS <= 6'h30; // use color quantization table (YCbCR, jp4diff)
component_firstsS <= 6'h31; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
end
3'h3:begin // jp4
cs_pre_first_out <= jp4_pre_first_out;
y_in[8:0] <= {jp4_y_in[7],jp4_y_in[7:0]};
ywe <= jp4_ywe;
yaddrw[7:0] <= {jp4_yaddrw[7],jp4_yaddrw[3],jp4_yaddrw[6:4],jp4_yaddrw[2:0]};
c_in[8:0] <= 9'h0;
cwe <= 1'b0;
pre_color_enable <= 1'b0;
caddrw[7:0] <= 8'h0;
ccv_out_start <= accYdone[0];
component_numsLS <= jp4_dc_improved_r?6'h0a:6'h10; // LSb of component_num
component_numsMS <= jp4_dc_improved_r?6'h0c:6'h20; // MSb of component_num
component_numsHS <= 6'h30; // component_num [2]
component_colorsS <= 6'h30; // use color quantization table (YCbCR, jp4diff)
component_firstsS <= jp4_dc_improved_r?6'h3f:6'h31; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
end
3'h4:begin //jp4diff
cs_pre_first_out <= jp4diff_pre_first_out;
y_in[8:0] <= {jp4diff_y_in[8:0]};
ywe <= jp4diff_ywe;
yaddrw[7:0] <= {jp4diff_yaddrw[7],jp4diff_yaddrw[3],jp4diff_yaddrw[6:4],jp4diff_yaddrw[2:0]};
c_in[8:0] <= 9'h0;
cwe <= 1'b0;
pre_color_enable <= 1'b0;
caddrw[7:0] <= 8'h0;
ccv_out_start <= accYdone[0];
component_numsLS <= 6'h0a; // LSb of component_num
component_numsMS <= 6'h0c; // MSb of component_num
component_numsHS <= 6'h30; // component_num [2]
component_colorsS <= {2'h3,~bayer_phase_onehot[3:0] | (hdr_r? {~bayer_phase_onehot[1:0],~bayer_phase_onehot[3:2]} : 4'h0)}; // use color quantization table (YCbCR, jp4diff)
component_firstsS <= 6'h3f; // first_r this component in a frame (DC absolute, otherwise - difference to previous)
end
endcase
wire limit_diff=1'b1;
csconvert18a i_csconvert18 (
.RST (!en_converters[0]),
.CLK (clk),
.mono (ignore_color_r),
.limit_diff (limit_diff), // 1 - limit color outputs to -128/+127 range, 0 - let them be limited downstream
.m_cb (m_cb[9:0]), // [9:0] scale for CB - default 0.564 (10'h90)
.m_cr (m_cr[9:0]), // [9:0] scale for CB - default 0.713 (10'hb6)
.din (di[7:0]),
.pre_first_in (first_pixel),
.signed_y (conv18_y_in[7:0]),
.q (conv18_c_in[8:0]),
.yaddr (conv18_yaddrw[7:0]), //
.ywe (conv18_ywe),
.caddr (conv18_caddrw[6:0]),
.cwe (conv18_cwe),
.pre_first_out (conv18_pre_first_out),
.bayer_phase (bayer_phase_r[1:0]),
.n000 (n000[7:0]), // TODO:remove ?
.n255 (n255[7:0]));
csconvert_mono i_csconvert_mono (
.en (en_converters[2]),
.clk (clk),
.din (di[7:0]),
.pre_first_in (first_pixel),
.y_out (mono_y_in[7:0]),
.yaddr (mono_yaddrw[7:0]),
.ywe (mono_ywe),
.pre_first_out(mono_pre_first_out));
csconvert_jp4 i_csconvert_jp4 (
.en (en_converters[3]),
.clk (clk),
.din (di[7:0]),
.pre_first_in (first_pixel),
.y_out (jp4_y_in[7:0]),
.yaddr (jp4_yaddrw[7:0]),
.ywe (jp4_ywe),
.pre_first_out (jp4_pre_first_out));
csconvert_jp4diff i_csconvert_jp4diff (
.en (en_converters[4]),
.clk (clk),
.scale_diff (scale_diff_r),
.hdr (hdr_r),
.din (di[7:0]),
.pre_first_in (first_pixel),
.y_out (jp4diff_y_in[8:0]),
.yaddr (jp4diff_yaddrw[7:0]),
.ywe (jp4diff_ywe),
.pre_first_out (jp4diff_pre_first_out),
.bayer_phase (bayer_phase_r[1:0]));
//TODO: temporary plugs, until module for 20x20 is created
// will be wrong, of course
assign conv20_y_in[7:0]= conv18_y_in[7:0];
assign conv20_yaddrw[7:0]= conv18_yaddrw[7:0];
assign conv20_ywe= conv18_ywe;
assign conv20_c_in[8:0]= conv18_c_in[8:0];
assign conv20_caddrw[6:0]= conv18_caddrw[6:0];
assign conv20_cwe= conv18_cwe;
assign conv20_pre_first_out= conv18_pre_first_out;
// currently only 8 bits are used in the memories
ram18p_var_w_var_r #(
.REGISTERS (1), // will need to delay output strobe(s) by 1
.LOG2WIDTH_WR (3),
.LOG2WIDTH_RD (3),
.DUMMY (0)
) i_y_buff (
.rclk (clk), // input
.raddr ({1'b0,rpage[1:0],raddr[7:0]}), // input[11:0]
.ren (!raddr[8]), // input
.regen (!raddr8_d), // input
.data_out (y_out[8:0]), // output[8:0]
.wclk (clk), // input
.waddr ({1'b0,wpage[1:0],yaddrw[7:0]}), // input[11:0]
.we (ywe), // input
.web (4'hf), // input[7:0]
.data_in (y_in[8:0]) // input[9:0]
);
ram18p_var_w_var_r #(
.REGISTERS (1), // will need to delay output strobe(s) by 1
.LOG2WIDTH_WR (3),
.LOG2WIDTH_RD (3),
.DUMMY (0)
) i_CrCb_buff (
.rclk (clk), // input
.raddr ({1'b0,rpage[1:0],raddr[7:0]}), // input[11:0]
.ren (raddr[8]), // input
.regen (raddr8_d), // input
.data_out (c_out[8:0]), // output[8:0]
.wclk (clk), // input
.waddr ({1'b0,wpage[1:0],yaddrw[7:0]}), // input[11:0]
.we (ywe), // input
.web (4'hf), // input[7:0]
.data_in (y_in[8:0]) // input[71:0]
);
/*
RAMB16_S9_S9 i_y_buff (
.DOA(), // Port A 8-bit Data Output
.DOPA(), // Port A 8-bit Parity Output
.ADDRA({1'b0,wpage[1:0],yaddrw[7:0]}), // Port A 11-bit Address Input
.CLKA(clk), // Port A Clock
.DIA(y_in[7:0]), // Port A 8-bit Data Input
.DIPA(y_in[8]), // Port A 1-bit parity Input
.ENA(ywe), // Port A RAM Enable Input
.SSRA(1'b0), // Port A Synchronous Set/Reset Input
.WEA(1'b1), // Port A Write Enable Input
.DOB(y_out[7:0]), // Port B 8-bit Data Output
.DOPB(y_out[8]), // Port B 1-bit Parity Output
.ADDRB({1'b0,rpage[1:0],raddr[7:0]}), // Port B 11-bit Address Input
.CLKB(clk), // Port B Clock
.DIB(8'h0), // Port B 8-bit Data Input
.DIPB(1'h0), // Port-B 1-bit parity Input
.ENB(!raddr[8]), // PortB RAM Enable Input
.SSRB(1'b0), // Port B Synchronous Set/Reset Input
.WEB(1'b0) // Port B Write Enable Input
);
RAMB16_S9_S9 i_CrCb_buff (
.DOA(), // Port A 8-bit Data Output
.DOPA(), // Port A 8-bit Parity Output
.ADDRA({1'b0,wpage[1:0],caddrw[7:0]}), // Port A 11-bit Address Input
.CLKA(clk), // Port A Clock
.DIA(c_in[7:0]), // Port A 8-bit Data Input
.DIPA(c_in[8]), // Port A 1-bit parity Input
.ENA(cwe), // Port A RAM Enable Input
.SSRA(1'b0), // Port A Synchronous Set/Reset Input
.WEA(1'b1), // Port A Write Enable Input
.DOB(c_out[7:0]), // Port B 8-bit Data Output
.DOPB(c_out[8]), // Port B 1-bit Parity Output
.ADDRB({1'b0,rpage[1:0],raddr[7:0]}), // Port B 11-bit Address Input
.CLKB(clk), // Port B Clock
.DIB(8'h0), // Port B 8-bit Data Input
.DIPB(1'h0), // Port-B 1-bit parity Input
.ENB(raddr[8]), // PortB RAM Enable Input
.SSRB(1'b0), // Port B Synchronous Set/Reset Input
.WEB(1'b0) // Port B Write Enable Input
);
*/
endmodule
...@@ -180,5 +180,5 @@ module cmd_encod_linear_rd #( ...@@ -180,5 +180,5 @@ module cmd_encod_linear_rd #(
// move to include? // move to include?
`include "includes/x393_mcontr_encode_cmd.vh" `include "includes/x393_mcontr_encode_cmd.vh"
/endmodule endmodule
...@@ -298,7 +298,7 @@ module cmd_encod_tiled_wr #( ...@@ -298,7 +298,7 @@ module cmd_encod_tiled_wr #(
fifo_2regs #( fifo_2regs #(
.WIDTH(COLADDR_NUMBER) .WIDTH(COLADDR_NUMBER)
) fifo_2regs_i ( ) fifo_2regs_i (
.mrst (rst), // input .mrst (mrst), // input
.clk (clk), // input .clk (clk), // input
.din (row_col_bank[COLADDR_NUMBER-1:0]), // input[15:0] .din (row_col_bank[COLADDR_NUMBER-1:0]), // input[15:0]
.wr(pre_act), // input .wr(pre_act), // input
......
...@@ -79,7 +79,8 @@ wire [9:0] decode_sel={ ...@@ -79,7 +79,8 @@ wire [9:0] decode_sel={
(dly_addr[3:0]==1)?1'b1:1'b0, (dly_addr[3:0]==1)?1'b1:1'b0,
(dly_addr[3:0]==0)?1'b1:1'b0}; (dly_addr[3:0]==0)?1'b1:1'b0};
always @ (posedge clk_div or posedge rst) begin //always @ (posedge clk_div or posedge rst) begin
always @ (posedge clk_div) begin
if (rst) begin if (rst) begin
din_r <= 32'b0; din_dm_r<=0; din_dqs_r<=0; tin_dq_r<=4'hf; tin_dqs_r<=4'hf; din_r <= 32'b0; din_dm_r<=0; din_dqs_r<=0; tin_dq_r<=4'hf; tin_dqs_r<=4'hf;
dly_data_r<=8'b0;set_r<=1'b0; dly_data_r<=8'b0;set_r<=1'b0;
...@@ -114,11 +115,8 @@ generate ...@@ -114,11 +115,8 @@ generate
.dci_disable(dci_disable_dq_r), // disable DCI termination during writes and idle .dci_disable(dci_disable_dq_r), // disable DCI termination during writes and idle
.dly_data(dly_data_r), // delay value (3 LSB - fine delay) .dly_data(dly_data_r), // delay value (3 LSB - fine delay)
.din({din_r[i+24],din_r[i+16],din_r[i+8],din_r[i]}) , // parallel data to be sent out .din({din_r[i+24],din_r[i+16],din_r[i+8],din_r[i]}) , // parallel data to be sent out
// .din(din_r[4*i+3:4*i]) , // parallel data to be sent out
// .din(din_r[4*i+3-:4]) , // parallel data to be sent out
.tin(tin_dq_r), // tristate for data out (sent out earlier than data!) .tin(tin_dq_r), // tristate for data out (sent out earlier than data!)
.dout({dout[i+24],dout[i+16],dout[i+8],dout[i]}), // parallel data received from DDR3 memory .dout({dout[i+24],dout[i+16],dout[i+8],dout[i]}), // parallel data received from DDR3 memory
// .dout(dout[4*i+3:4*i]), // parallel data received from DDR3 memory
.set_odelay(set_r), // clk_div synchronous load odelay value from dly_data .set_odelay(set_r), // clk_div synchronous load odelay value from dly_data
.ld_odelay(ld_odly[i]), // clk_div synchronous set odealy value from loaded .ld_odelay(ld_odly[i]), // clk_div synchronous set odealy value from loaded
.set_idelay(set_r), // clk_div synchronous load idelay value from dly_data .set_idelay(set_r), // clk_div synchronous load idelay value from dly_data
......
...@@ -80,11 +80,11 @@ assign decode_addr24={ ...@@ -80,11 +80,11 @@ assign decode_addr24={
(dly_addr[4:3] == 2'h2)?decode_sel[7:0]:8'h0, (dly_addr[4:3] == 2'h2)?decode_sel[7:0]:8'h0,
(dly_addr[4:3] == 2'h1)?decode_sel[7:0]:8'h0, (dly_addr[4:3] == 2'h1)?decode_sel[7:0]:8'h0,
(dly_addr[4:3] == 2'h0)?decode_sel[7:0]:8'h0}; (dly_addr[4:3] == 2'h0)?decode_sel[7:0]:8'h0};
always @ (posedge clk_div or posedge rst) begin //always @ (posedge clk_div or posedge rst) begin
always @ (posedge clk_div) begin
if (rst) begin if (rst) begin
in_a_r <= 0; in_ba_r <= 6'b0; in_a_r <= 0; in_ba_r <= 6'b0;
in_we_r <= 2'h3; in_ras_r <= 2'h3; in_cas_r <= 2'h3; in_cke_r <= 2'h3; in_odt_r <= 2'h0; in_we_r <= 2'h3; in_ras_r <= 2'h3; in_cas_r <= 2'h3; in_cke_r <= 2'h3; in_odt_r <= 2'h0;
// in_tri_r <= 2'h0; // or tri-state on reset?
in_tri_r <= 1'b1; // or tri-state on reset? in_tri_r <= 1'b1; // or tri-state on reset?
dly_data_r<=8'b0;set_r<=1'b0; dly_data_r<=8'b0;set_r<=1'b0;
ld_dly_cmd <= 8'b0; ld_dly_addr <= 0; ld_dly_cmd <= 8'b0; ld_dly_addr <= 0;
......
/*******************************************************************************
* Module: ddrc_sequencer
* Date:2014-05-16
* Author: Andrey Filippov
* Description: ddr3 sequnecer
*
* Copyright (c) 2014 Elphel, Inc.
* ddrc_sequencer.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.
*
* ddrc_sequencer.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
module ddrc_sequencer #(
parameter PHASE_WIDTH = 8,
parameter SLEW_DQ = "SLOW",
parameter SLEW_DQS = "SLOW",
parameter SLEW_CMDA = "SLOW",
parameter SLEW_CLK = "SLOW",
parameter IBUF_LOW_PWR = "TRUE",
parameter real REFCLK_FREQUENCY = 300.0,
parameter HIGH_PERFORMANCE_MODE = "FALSE",
parameter CLKIN_PERIOD = 10, //ns >1.25, 600<Fvco<1200
parameter CLKFBOUT_MULT = 8, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE
parameter CLKFBOUT_MULT_REF = 9, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE
parameter CLKFBOUT_DIV_REF = 3, // To get 300MHz for the reference clock
parameter DIVCLK_DIVIDE= 1,
parameter CLKFBOUT_PHASE = 0.000,
parameter SDCLK_PHASE = 0.000,
parameter CLK_PHASE = 0.000,
parameter CLK_DIV_PHASE = 0.000,
parameter MCLK_PHASE = 90.000,
parameter REF_JITTER1 = 0.010,
parameter SS_EN = "FALSE",
parameter SS_MODE = "CENTER_HIGH",
parameter SS_MOD_PERIOD = 10000,
parameter CMD_PAUSE_BITS= 10,
parameter CMD_DONE_BIT= 10
)(
// DDR3 interface
output SDRST, // DDR3 reset (active low)
output SDCLK, // DDR3 clock differential output, positive
output SDNCLK,// DDR3 clock differential output, negative
output [ADDRESS_NUMBER-1:0] SDA, // output address ports (14:0) for 4Gb device
output [2:0] SDBA, // output bank address ports
output SDWE, // output WE port
output SDRAS, // output RAS port
output SDCAS, // output CAS port
output SDCKE, // output Clock Enable port
output SDODT, // output ODT port
inout [15:0] SDD, // DQ I/O pads
output SDDML, // LDM I/O pad (actually only output)
inout DQSL, // LDQS I/O pad
inout NDQSL, // ~LDQS I/O pad
output SDDMU, // UDM I/O pad (actually only output)
inout DQSU, // UDQS I/O pad
inout NDQSU, // ~UDQS I/O pad
// clocks, reset
input clk_in,
input rst_in,
output mclk, // global clock, half DDR3 clock, synchronizes all I/O through the command port
// command port 0 (filled by software - 32w->32r) - used for mode set, refresh, write levelling, ...
input cmd0_clk,
input cmd0_we,
input [9:0] cmd0_addr,
input [31:0] cmd0_data,
// automatic command port1 , filled by the PL, 32w 32r, used for actual page R/W
input cmd1_clk,
input cmd1_we,
input [9:0] cmd1_addr,
input [31:0] cmd1_data,
// Controller run interface, posedge mclk
input [10:0] run_addr, // controller sequencer start address (0..11'h3ff - cmd0, 11'h400..11'h7ff - cmd1)
input [3:0] run_chn, // data channel to use
input run_seq, // start controller sequence (will and with !ddr_rst for stable mclk)
output run_done, // controller sequence finished
output run_busy, // controller sequence in progress
// inteface to control I/O delays and mmcm
input [7:0] dly_data, // delay value (3 LSB - fine delay)
input [6:0] dly_addr, // select which delay to program
input ld_delay, // load delay data to selected iodelayl (clk_div synchronous)
input set, // clk_div synchronous set all delays from previously loaded values
// output locked,
output locked_mmcm,
output locked_pll,
output dly_ready,
output dci_ready,
output phy_locked_mmcm,
output phy_locked_pll,
output phy_dly_ready,
output phy_dci_ready,
output [7:0] tmp_debug,
output ps_rdy,
output [PHASE_WIDTH-1:0] ps_out,
// read port 0
input port0_clk,
input port0_re,
input port0_regen,
input [1:0] port0_page,
input [1:0] port0_int_page,
input [7:0] port0_addr,
output [31:0] port0_data,
// write port 1
input port1_clk,
input port1_we,
input [1:0] port1_page,
input [1:0] port1_int_page,
input [7:0] port1_addr,
input [31:0] port1_data,
// extras
input cmda_en, // enable (!tristate) command and address lines // not likely to be used
input ddr_rst, // generate reset to DDR3 memory (active high)
input dci_rst, // active high - reset DCI circuitry
input dly_rst, // active high - delay calibration circuitry
input ddr_cke, // DDR clock enable , XOR-ed with command bit
input inv_clk_div,
input [7:0] dqs_pattern, // 8'h55
input [7:0] dqm_pattern, // 8'h00
input [ 3:0] dq_tri_on_pattern, // DQ tri-state control word, first when enabling output
input [ 3:0] dq_tri_off_pattern, // DQ tri-state control word, first after disabling output
input [ 3:0] dqs_tri_on_pattern, // DQS tri-state control word, first when enabling output
input [ 3:0] dqs_tri_off_pattern,// DQS tri-state control word, first after disabling output
input [ 3:0] wbuf_delay
);
localparam ADDRESS_NUMBER = 15;
// wire [35:0] phy_cmd; // input[35:0]
wire [31:0] phy_cmd_word; // selected output from eithe cmd0 buffer or cmd1 buffer
wire [31:0] phy_cmd0_word; // cmd0 buffer output
wire [31:0] phy_cmd1_word; // cmd1 buffer output
reg [ 8:0] buf_raddr;
reg [ 8:0] buf_waddr_negedge;
reg buf_wr_negedge;
wire [63:0] buf_wdata; // output[63:0]
reg [63:0] buf_wdata_negedge; // output[63:0]
wire [63:0] buf_rdata; // multiplexed input from one of the write channels buffer
wire [63:0] buf1_rdata;
wire buf_wr; // delayed by specified number of clock cycles
wire buf_wr_ndly; // before dealy
wire buf_rd; // read next 64 bytes from the buffer, need one extra pre-read
wire rst=rst_in;
// wire [ 9:0] next_cmd_addr;
reg [ 9:0] cmd_addr; // command word address
reg cmd_sel;
reg [ 2:0] cmd_busy; // bit 0 - immediately,
wire phy_cmd_nop; // decoded command (ras, cas, we) was NOP
wire phy_cmd_add_pause; // decoded from the command word - add one pause command after the current one
reg add_pause; // previos command had phy_cmd_add_pause set
wire sequence_done;
wire [CMD_PAUSE_BITS-1:0] pause_len;
reg cmd_fetch; // previous cycle command was read from the command memory, current: command valid
wire pause; // do not register new data from the command memory
reg [CMD_PAUSE_BITS-1:0] pause_cntr;
reg [1:0] buf_page; // one of 4 pages in the channel buffer to use for R/W
reg [15:0] buf_sel_1hot; // 1 hot channel buffer select
reg [3:0] run_chn_d;
reg run_seq_d;
// reg tmp_dbg7=0;
wire [7:0] tmp_debug_a;
/*
always @ (posedge clk_in) begin
tmp_dbg7 <= ~tmp_dbg7;
end
assign tmp_debug[7:0] = {tmp_dbg7,tmp_debug_a[6:0]};
*/
assign tmp_debug[7:0] = tmp_debug_a[7:0];
// clk_in
assign run_done=sequence_done;
assign run_busy=cmd_busy[0]; //earliest
assign pause=cmd_fetch? (phy_cmd_add_pause || (phy_cmd_nop && (pause_len != 0))): (cmd_busy[2] && (pause_cntr[CMD_PAUSE_BITS-1:1]!=0));
/// debugging
assign phy_cmd_word = cmd_sel?phy_cmd1_word:phy_cmd0_word; // TODO: hangs even with 0-s in phy_cmd
/// assign phy_cmd_word = phy_cmd_word?0:0;
assign buf_rdata[63:0] = ({64{buf_sel_1hot[1]}} & buf1_rdata[63:0]); // ORed with other read channels terms
always @ (posedge mclk or posedge rst) begin
if (rst) cmd_busy <= 0;
// else if (sequence_done) cmd_busy <= 0;
else if (ddr_rst) cmd_busy <= 0; // *************** reset sequencer with DDR reset
else if (sequence_done && cmd_busy[2]) cmd_busy <= 0;
else cmd_busy <= {cmd_busy[1:0],run_seq | cmd_busy[0]};
// Pause counter
if (rst) pause_cntr <= 0;
else if (!cmd_busy[1]) pause_cntr <= 0; // not needed?
else if (cmd_fetch && phy_cmd_nop) pause_cntr <= pause_len;
else if (pause_cntr!=0) pause_cntr <= pause_cntr-1; //SuppressThisWarning ISExst Result of 32-bit expression is truncated to fit in 10-bit target.
// Fetch - command data valid
if (rst) cmd_fetch <= 0;
else cmd_fetch <= cmd_busy[0] && !pause;
if (rst) add_pause <= 0;
else add_pause <= cmd_fetch && phy_cmd_add_pause;
// Command read address
if (rst) cmd_addr <= 0;
else if (run_seq) cmd_addr <= run_addr[9:0];
else if (cmd_busy[0] && !pause) cmd_addr <= cmd_addr + 1; //SuppressThisWarning ISExst Result of 11-bit expression is truncated to fit in 10-bit target.
// command bank select (0 - "manual" (software programmed sequences), 1 - "auto" (normal block r/w)
if (rst) cmd_sel <= 0;
else if (run_seq) cmd_sel <= run_addr[10];
if (rst) buf_page <= 0;
else if (run_seq) case (run_chn)
4'h0: buf_page <= port0_int_page;
4'h1: buf_page <= port1_int_page;
// Add other channels later
default: buf_page <= 2'bxx;
endcase
if (rst) buf_sel_1hot <= 0;
else buf_sel_1hot <= {
(run_chn_d==4'hf)?1'b1:1'b0,
(run_chn_d==4'he)?1'b1:1'b0,
(run_chn_d==4'hd)?1'b1:1'b0,
(run_chn_d==4'hc)?1'b1:1'b0,
(run_chn_d==4'hb)?1'b1:1'b0,
(run_chn_d==4'ha)?1'b1:1'b0,
(run_chn_d==4'h9)?1'b1:1'b0,
(run_chn_d==4'h8)?1'b1:1'b0,
(run_chn_d==4'h7)?1'b1:1'b0,
(run_chn_d==4'h6)?1'b1:1'b0,
(run_chn_d==4'h5)?1'b1:1'b0,
(run_chn_d==4'h4)?1'b1:1'b0,
(run_chn_d==4'h3)?1'b1:1'b0,
(run_chn_d==4'h2)?1'b1:1'b0,
(run_chn_d==4'h1)?1'b1:1'b0,
(run_chn_d==4'h0)?1'b1:1'b0 };
if (rst) buf_raddr <= 9'h0;
else if (run_seq_d) buf_raddr <= {buf_page,7'h0};
else if (buf_wr || buf_rd) buf_raddr <= buf_raddr +1; // Separate read/write address? read address re-registered @ negedge //SuppressThisWarning ISExst Result of 10-bit expression is truncated to fit in 9-bit target.
if (rst) run_chn_d <= 0;
else if (run_seq) run_chn_d <= run_chn;
if (rst) run_seq_d <= 0;
else run_seq_d <= run_seq;
end
// re-register buffer write address to match DDR3 data
always @ (negedge mclk) begin
buf_waddr_negedge <= buf_raddr;
buf_wr_negedge <= buf_wr;
buf_wdata_negedge <= buf_wdata;
end
// Command sequence memories:
// Command sequence memory 0 ("manual"):
wire ren0=!cmd_sel && cmd_busy[0] && !pause; // cmd_busy - multibit
wire ren1= cmd_sel && cmd_busy[0] && !pause;
ram_1kx32_1kx32 #(
.REGISTERS(1) // (0) // register output
) cmd0_buf_i (
.rclk (mclk), // input
.raddr (cmd_addr), // input[9:0]
/// .ren (!cmd_sel && cmd_busy && !pause), // input
/// .regen (!cmd_sel && cmd_busy && !pause), // input
.ren (ren0), // input TODO: verify cmd_busy[0] is correct (was cmd_busy )
.regen (ren0), // input
.data_out (phy_cmd0_word), // output[31:0]
.wclk (cmd0_clk), // input
.waddr (cmd0_addr), // input[9:0]
.we (cmd0_we), // input
.web (4'hf), // input[3:0]
.data_in (cmd0_data) // input[31:0]
);
// Command sequence memory 0 ("manual"):
ram_1kx32_1kx32 #(
.REGISTERS(1) // (0) // register output
) cmd1_buf_i (
.rclk (mclk), // input
.raddr (cmd_addr), // input[9:0]
/// .ren ( cmd_sel && cmd_busy && !pause), // input
/// .regen ( cmd_sel && cmd_busy && !pause), // input
.ren ( ren1), // input
.regen ( ren1), // input
.data_out (phy_cmd1_word), // output[31:0]
.wclk (cmd1_clk), // input
.waddr (cmd1_addr), // input[9:0]
.we (cmd1_we), // input
.web (4'hf), // input[3:0]
.data_in (cmd1_data) // input[31:0]
);
// Port memory buffer (4 pages each, R/W fixed, port 0 - AXI read from DDR, port 1 - AXI write to DDR
// Port 0 (read DDR to AXI) buffer
ram_512x64w_1kx32r #(
.REGISTERS(1)
) port0_buf_i (
.rclk (port0_clk), // input
.raddr ({port0_page,port0_addr}), // input[9:0]
.ren (port0_re), // input
.regen (port0_regen), // input
.data_out (port0_data), // output[31:0]
.wclk (!mclk), // input
.waddr (buf_waddr_negedge), // input[8:0]
.we (buf_sel_1hot[0] && buf_wr_negedge), // input
.web (8'hff), // input[7:0]
.data_in (buf_wdata_negedge) // input[63:0]
);
// Port 1 (write DDR from AXI) buffer
ram_1kx32w_512x64r #(
.REGISTERS(1)
) port1_buf_i (
.rclk(mclk), // input
.raddr(buf_raddr), // input[8:0]
.ren(buf_sel_1hot[1] && buf_rd), // input
.regen(buf_sel_1hot[1] && buf_rd), // input
.data_out(buf1_rdata), // output[63:0]
.wclk(port1_clk), // input
.waddr({port1_page,port1_addr}), // input[9:0]
.we(port1_we), // input
.web(4'hf), // input[3:0]
.data_in(port1_data) // input[31:0]
);
phy_cmd #(
.ADDRESS_NUMBER (ADDRESS_NUMBER),
.PHASE_WIDTH (PHASE_WIDTH),
.SLEW_DQ (SLEW_DQ),
.SLEW_DQS (SLEW_DQS),
.SLEW_CMDA (SLEW_CMDA),
.SLEW_CLK (SLEW_CLK),
.IBUF_LOW_PWR (IBUF_LOW_PWR),
.REFCLK_FREQUENCY (REFCLK_FREQUENCY),
.HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE),
.CLKIN_PERIOD (CLKIN_PERIOD),
.CLKFBOUT_MULT (CLKFBOUT_MULT),
.CLKFBOUT_MULT_REF (CLKFBOUT_MULT_REF),
.CLKFBOUT_DIV_REF (CLKFBOUT_DIV_REF),
.DIVCLK_DIVIDE (DIVCLK_DIVIDE),
.CLKFBOUT_PHASE (CLKFBOUT_PHASE),
.SDCLK_PHASE (SDCLK_PHASE),/// debugging
.CLK_PHASE (CLK_PHASE),
.CLK_DIV_PHASE (CLK_DIV_PHASE),
.MCLK_PHASE (MCLK_PHASE),
.REF_JITTER1 (REF_JITTER1),
.SS_EN (SS_EN),
.SS_MODE (SS_MODE),
.SS_MOD_PERIOD (SS_MOD_PERIOD),
.CMD_PAUSE_BITS (CMD_PAUSE_BITS), // numer of (address) bits to encode pause
.CMD_DONE_BIT (CMD_DONE_BIT) // bit number (address) to signal sequence done
) phy_cmd_i (
.SDRST (SDRST), // output
.SDCLK (SDCLK), // output
.SDNCLK (SDNCLK), // output
.SDA (SDA[ADDRESS_NUMBER-1:0]), // output[14:0]
.SDBA (SDBA[2:0]), // output[2:0]
.SDWE (SDWE), // output
.SDRAS (SDRAS), // output
.SDCAS (SDCAS), // output
.SDCKE (SDCKE), // output
.SDODT (SDODT), // output
.SDD (SDD[15:0]), // inout[15:0]
.SDDML (SDDML), // inout
.DQSL (DQSL), // inout
.NDQSL (NDQSL), // inout
.SDDMU (SDDMU), // inout
.DQSU (DQSU), // inout
.NDQSU (NDQSU), // inout
.clk_in (clk_in), // input
.rst_in (rst_in), // input
.mclk (mclk), // output
.dly_data (dly_data[7:0]), // input[7:0]
.dly_addr (dly_addr[6:0]), // input[6:0]
.ld_delay (ld_delay), // input
.set (set), // input
// .locked (locked), // output
.locked_mmcm (locked_mmcm), // output
.locked_pll (locked_pll), // output
.dly_ready (dly_ready), // output
.dci_ready (dci_ready), // output
.phy_locked_mmcm (phy_locked_mmcm), // output
.phy_locked_pll (phy_locked_pll), // output
.phy_dly_ready (phy_dly_ready), // output
.phy_dci_ready (phy_dci_ready), // output
.tmp_debug (tmp_debug_a[7:0]),
.ps_rdy (ps_rdy), // output
.ps_out (ps_out[7:0]), // output[7:0]
.phy_cmd_word (phy_cmd_word[31:0]), // input[31:0]
.phy_cmd_nop (phy_cmd_nop), // output
.phy_cmd_add_pause (phy_cmd_add_pause), // one pause cycle (for 8-bursts)
.add_pause (add_pause),
.pause_len (pause_len), // output [CMD_PAUSE_BITS-1:0]
.sequence_done (sequence_done), // output
.buf_wdata (buf_wdata[63:0]), // output[63:0]
.buf_rdata (buf_rdata[63:0]), // input[63:0]
.buf_wr (buf_wr_ndly), // output
.buf_rd (buf_rd), // output
.buf_rst (), // output
.cmda_en (cmda_en), // input
.ddr_rst (ddr_rst), // input
.dci_rst (dci_rst), // input
.dly_rst (dly_rst), // input
.ddr_cke (ddr_cke), // input
.inv_clk_div (inv_clk_div), // input
.dqs_pattern (dqs_pattern), // input[7:0]
.dqm_pattern (dqm_pattern), // input[7:0]
.dq_tri_on_pattern (dq_tri_on_pattern[3:0]), // input[3:0]
.dq_tri_off_pattern (dq_tri_off_pattern[3:0]), // input[3:0]
.dqs_tri_on_pattern (dqs_tri_on_pattern[3:0]), // input[3:0]
.dqs_tri_off_pattern (dqs_tri_off_pattern[3:0]) // input[3:0]
);
// delay buf_wr by 1-16 cycles to compensate for DDR and HDL code latency (~7 cycles?)
dly01_16 buf_wr_dly_i (
.clk(mclk), // input
.rst(1'b0), // input
.dly(wbuf_delay[3:0]), // input[3:0]
.din(buf_wr_ndly), // input
.dout(buf_wr) // output reg
);
endmodule
...@@ -125,7 +125,8 @@ module phy_top #( ...@@ -125,7 +125,8 @@ module phy_top #(
// else rst <= 1'b0; // else rst <= 1'b0;
// end // end
always @(negedge clk_div) begin // Why is it @ negedge clk_div? // always @(negedge clk_div) begin // Why is it @ negedge clk_div?
always @(posedge clk_div) begin // Why is it @ negedge clk_div?
if (mrst) rst <= 1'b1; if (mrst) rst <= 1'b1;
else rst <= 1'b0; else rst <= 1'b0;
end end
......
// This file may be used to define same pre-processor macros to be included into each parsed file // This file may be used to define same pre-processor macros to be included into each parsed file
`ifndef SYSTEM_DEFINES `ifndef SYSTEM_DEFINES
`define SYSTEM_DEFINES `define SYSTEM_DEFINES
// will not use simultaneous reset in shift registers, just and input data with ~rst
`define SHREG_SEQUENTIAL_RESET 1
//`define MEMBRIDGE_DEBUG_READ 1 //`define MEMBRIDGE_DEBUG_READ 1
`define use200Mhz 1 `define use200Mhz 1
`define USE_CMD_ENCOD_TILED_32_RD 1 `define USE_CMD_ENCOD_TILED_32_RD 1
......
...@@ -458,12 +458,12 @@ module camsync393 #( ...@@ -458,12 +458,12 @@ module camsync393 #(
end end
`ifdef GENERATE_TRIG_OVERDUE `ifdef GENERATE_TRIG_OVERDUE
always @ (posedge rst or posedge mclk) begin always @ (posedge mclk) begin
if (rst) trigger_r <= 0; if (mrst) trigger_r <= 0;
else if (!triggered_mode) trigger_r <= 0; else if (!triggered_mode) trigger_r <= 0;
else trigger_r <= ~frame_sync & (trig_r_mclk ^ trigger_r); else trigger_r <= ~frame_sync & (trig_r_mclk ^ trigger_r);
if (rst) overdue <= 0; if (mrst) overdue <= 0;
else if (!triggered_mode) overdue <= 0; else if (!triggered_mode) overdue <= 0;
else overdue <= ((overdue ^ trigger_r) & trig_r_mclk) ^ overdue; else overdue <= ((overdue ^ trigger_r) & trig_r_mclk) ^ overdue;
......
...@@ -28,11 +28,17 @@ module dly01_16( ...@@ -28,11 +28,17 @@ module dly01_16(
output reg dout output reg dout
); );
reg [15:0] sr=0; reg [15:0] sr=0;
always @ (posedge rst or posedge clk) begin `ifdef SHREG_SEQUENTIAL_RESET
always @ (posedge clk) begin
sr <= {sr[14:0], din & ~rst};
end
`else
// always @ (posedge rst or posedge clk) begin
always @ (posedge clk) begin
if (rst) sr <=0; if (rst) sr <=0;
else sr <= {sr[14:0],din}; else sr <= {sr[14:0],din};
end end
`endif
always @ (sr or dly) case (dly) always @ (sr or dly) case (dly)
4'h0: dout <= sr[ 0]; 4'h0: dout <= sr[ 0];
4'h1: dout <= sr[ 1]; 4'h1: dout <= sr[ 1];
......
...@@ -87,8 +87,8 @@ module gpio393 #( ...@@ -87,8 +87,8 @@ module gpio393 #(
input [GPIO_N-1:0] dc, // port A data input [GPIO_N-1:0] dc, // port A data
input [GPIO_N-1:0] dc_en); // port A data enable input [GPIO_N-1:0] dc_en); // port A data enable
wire [GPIO_N-1:0] ds = 0; // "software" data (programmed by lower 24 bits) wire [GPIO_N-1:0] ds; // "software" data (programmed by lower 24 bits)
wire [GPIO_N-1:0] ds_en = 0; // "software" data enable (programmed by lower 24 bits) wire [GPIO_N-1:0] ds_en; // "software" data enable (programmed by lower 24 bits)
reg [3:0] ch_en = 0; // channel enable reg [3:0] ch_en = 0; // channel enable
wire [31:0] cmd_data; wire [31:0] cmd_data;
...@@ -119,6 +119,7 @@ module gpio393 #( ...@@ -119,6 +119,7 @@ module gpio393 #(
(da_en_m & da) | (da_en_m & da) |
(ds_en_m & ds); (ds_en_m & ds);
assign io_t = ~(dc_en_m | db_en_m | da_en_m | ds_en_m); assign io_t = ~(dc_en_m | db_en_m | da_en_m | ds_en_m);
// 0 0 0 - no change - // 0 0 0 - no change -
// 0 1 1 1 0 // 0 1 1 1 0
// 1 0 2 1 1 // 1 0 2 1 1
......
...@@ -29,41 +29,31 @@ module mcont_from_chnbuf_reg #( ...@@ -29,41 +29,31 @@ module mcont_from_chnbuf_reg #(
input ext_buf_rd, input ext_buf_rd,
input [3:0] ext_buf_rchn, // ==run_chn_d valid 1 cycle ahead opf ext_buf_rd!, maybe not needed - will be generated externally input [3:0] ext_buf_rchn, // ==run_chn_d valid 1 cycle ahead opf ext_buf_rd!, maybe not needed - will be generated externally
input ext_buf_rrefresh, input ext_buf_rrefresh,
// input ext_buf_rrun,
input ext_buf_rpage_nxt, input ext_buf_rpage_nxt,
output reg [63:0] ext_buf_rdata, // Latency of ram_1kx32w_512x64r plus 2 output reg [63:0] ext_buf_rdata, // Latency of ram_1kx32w_512x64r plus 2
output reg buf_rd_chn, output reg buf_rd_chn,
// output reg buf_run,
output reg rpage_nxt, output reg rpage_nxt,
input [63:0] buf_rdata_chn input [63:0] buf_rdata_chn
); );
reg [63:0] buf_rdata_chn_r; /// *** temporary register to delay buffer read data - may be used to implement multi-clock mux to ease timing reg [63:0] buf_rdata_chn_r; /// *** temporary register to delay buffer read data - may be used to implement multi-clock mux to ease timing
reg buf_chn_sel; reg buf_chn_sel;
reg [CHN_LATENCY:0] latency_reg=0; reg [CHN_LATENCY:0] latency_reg=0;
always @ (posedge rst or posedge clk) begin // always @ (posedge rst or posedge clk) begin
always @ (posedge clk) begin
if (rst) buf_chn_sel <= 0; if (rst) buf_chn_sel <= 0;
else buf_chn_sel <= (ext_buf_rchn==CHN_NUMBER) && !ext_buf_rrefresh; else buf_chn_sel <= (ext_buf_rchn==CHN_NUMBER) && !ext_buf_rrefresh;
if (rst) buf_rd_chn <= 0; if (rst) buf_rd_chn <= 0;
else buf_rd_chn <= buf_chn_sel && ext_buf_rd; else buf_rd_chn <= buf_chn_sel && ext_buf_rd;
// if (rst) buf_run <= 0;
// else buf_run <= (ext_buf_rchn==CHN_NUMBER) && !ext_buf_rrefresh && ext_buf_rrun;
if (rst) latency_reg<= 0; if (rst) latency_reg<= 0;
// else latency_reg <= buf_rd_chn | (latency_reg << 1);
else latency_reg <= {latency_reg[CHN_LATENCY-1:0], buf_rd_chn}; else latency_reg <= {latency_reg[CHN_LATENCY-1:0], buf_rd_chn};
// if (rst) buf_done <= 0;
// else buf_done <= buf_chn_sel && seq_done;
end end
// always @ (posedge clk) buf_raddr_rst_chn <= ext_buf_raddr_rst && (ext_buf_rchn==CHN_NUMBER);
// always @ (posedge clk) if (buf_chn_sel && ext_buf_rd) buf_raddr_chn <= ext_buf_raddr;
// always @ (posedge clk) if (latency_reg[CHN_LATENCY]) ext_buf_rdata <= buf_rdata_chn;
always @ (posedge clk) buf_rdata_chn_r <= buf_rdata_chn; // THIS WILL BE REPLACED BY MULTI-CYCLE MUX always @ (posedge clk) buf_rdata_chn_r <= buf_rdata_chn; // THIS WILL BE REPLACED BY MULTI-CYCLE MUX
always @ (posedge clk) if (latency_reg[CHN_LATENCY]) ext_buf_rdata <= buf_rdata_chn_r; always @ (posedge clk) if (latency_reg[CHN_LATENCY]) ext_buf_rdata <= buf_rdata_chn_r;
always @ (posedge clk) rpage_nxt <= ext_buf_rpage_nxt && (ext_buf_rchn==CHN_NUMBER) && !ext_buf_rrefresh; always @ (posedge clk) rpage_nxt <= ext_buf_rpage_nxt && (ext_buf_rchn==CHN_NUMBER) && !ext_buf_rrefresh;
//buf_rdata_chn_r
endmodule endmodule
...@@ -37,9 +37,10 @@ module idelay_fine_pipe ...@@ -37,9 +37,10 @@ module idelay_fine_pipe
); );
reg [2:0] fdly_pre=DELAY_VALUE[2:0], fdly=DELAY_VALUE[2:0]; reg [2:0] fdly_pre=DELAY_VALUE[2:0], fdly=DELAY_VALUE[2:0];
always @ (posedge clk or posedge rst) begin always @ (posedge clk) begin
if (rst) fdly_pre <= DELAY_VALUE[2:0]; if (rst) fdly_pre <= DELAY_VALUE[2:0];
else if (ld) fdly_pre <= delay[2:0]; else if (ld) fdly_pre <= delay[2:0];
if (rst) fdly <= DELAY_VALUE[2:0]; if (rst) fdly <= DELAY_VALUE[2:0];
else if (set) fdly <= fdly_pre; else if (set) fdly <= fdly_pre;
end end
......
...@@ -116,7 +116,7 @@ module mmcm_phase_cntr#( ...@@ -116,7 +116,7 @@ module mmcm_phase_cntr#(
// made a difference, so it doesn't seem Vivado extends bits of operands "+", "-" // made a difference, so it doesn't seem Vivado extends bits of operands "+", "-"
wire [PHASE_WIDTH:0] diff= {ps_target[PHASE_WIDTH-1],ps_target}-{ps_dout_r[PHASE_WIDTH-1],ps_dout_r}; wire [PHASE_WIDTH:0] diff= {ps_target[PHASE_WIDTH-1],ps_target}-{ps_dout_r[PHASE_WIDTH-1],ps_dout_r};
assign ps_dout = ps_dout_r; assign ps_dout = ps_dout_r;
always @ (posedge psclk or posedge rst) begin always @ (posedge psclk) begin
if (rst) ps_start0 <= 0; if (rst) ps_start0 <= 0;
else ps_start0 <= ps_we && ps_ready; else ps_start0 <= ps_we && ps_ready;
......
...@@ -36,9 +36,10 @@ module odelay_fine_pipe ...@@ -36,9 +36,10 @@ module odelay_fine_pipe
output data_out output data_out
); );
reg [2:0] fdly_pre=DELAY_VALUE[2:0], fdly=DELAY_VALUE[2:0]; reg [2:0] fdly_pre=DELAY_VALUE[2:0], fdly=DELAY_VALUE[2:0];
always @ (posedge clk or posedge rst) begin always @ (posedge clk) begin
if (rst) fdly_pre <= DELAY_VALUE[2:0]; if (rst) fdly_pre <= DELAY_VALUE[2:0];
else if (ld) fdly_pre <= delay[2:0]; else if (ld) fdly_pre <= delay[2:0];
if (rst) fdly <= DELAY_VALUE[2:0]; if (rst) fdly <= DELAY_VALUE[2:0];
else if (set) fdly <= fdly_pre; else if (set) fdly <= fdly_pre;
end end
......
...@@ -2080,7 +2080,7 @@ assign axi_grst = axi_rst_pre; ...@@ -2080,7 +2080,7 @@ assign axi_grst = axi_rst_pre;
.WIDTH(7), .WIDTH(7),
.REGISTER(4) .REGISTER(4)
) sync_resets_i ( ) sync_resets_i (
.arst(), // input .arst (axi_rst_pre), // input
.locked ({locked_hclk, 1'b1, locked_sync_clk, locked_sync_clk, locked_xclk, locked_pclk, mcntrl_locked}), // input .locked ({locked_hclk, 1'b1, locked_sync_clk, locked_sync_clk, locked_xclk, locked_pclk, mcntrl_locked}), // input
.clk ({hclk, axi_aclk, logger_clk, camsync_clk, xclk, pclk, mclk}), // input[6:0] .clk ({hclk, axi_aclk, logger_clk, camsync_clk, xclk, pclk, mclk}), // input[6:0]
.rst ({hrst, arst, lrst, crst, xrst, prst, mrst}) // output[6:0] .rst ({hrst, arst, lrst, crst, xrst, prst, mrst}) // output[6:0]
......
...@@ -21,6 +21,16 @@ ...@@ -21,6 +21,16 @@
#http://forums.xilinx.com/t5/7-Series-FPGAs/MMCM-reference-clock-muxing/td-p/550622 #http://forums.xilinx.com/t5/7-Series-FPGAs/MMCM-reference-clock-muxing/td-p/550622
set_property is_enabled false [get_drc_checks REQP-119] set_property is_enabled false [get_drc_checks REQP-119]
#Input Buffer Connections .. has no loads. An input buffer must drive an internal load.
set_property is_enabled false [get_drc_checks BUFC-1]
#DSP Buffering:
set_property is_enabled false [get_drc_checks DPIP-1]
set_property is_enabled false [get_drc_checks DPOP-1]
#MMCME2_ADV connectivity violation
set_property is_enabled false [get_drc_checks REQP-1577]
#Synchronous clocking for BRAM (mult_saxi_wr_inbuf_i/ram_var_w_var_r_i/ram_i/RAMB36E1_i) in SDP mode ...
set_property is_enabled false [get_drc_checks REQP-165]
# output SDRST, // output SDRST, active low # output SDRST, // output SDRST, active low
......
...@@ -76,10 +76,36 @@ create_generated_clock -name ddr3_mclk [get_nets -hierarchical mclk_pre] ...@@ -76,10 +76,36 @@ create_generated_clock -name ddr3_mclk [get_nets -hierarchical mclk_pre]
create_generated_clock -name ddr3_clk_ref [get_nets -hierarchical clk_ref_pre ] create_generated_clock -name ddr3_clk_ref [get_nets -hierarchical clk_ref_pre ]
create_generated_clock -name axihp_clk [get_nets clocks393_i/dual_clock_axihp_i/clk1x_pre ] create_generated_clock -name axihp_clk [get_nets clocks393_i/dual_clock_axihp_i/clk1x_pre ]
create_generated_clock -name xclk [get_nets clocks393_i/dual_clock_xclk_i/clk1x_pre ]
create_generated_clock -name xclk2x [get_nets clocks393_i/dual_clock_xclk_i/clk2x_pre ]
create_clock -name ffclk0 -period 41.667 [get_ports {ffclk0p}]
#Generated clocks are assumed to be tied to clkin1 (not 2), so until external ffclk0 is constrained, derivative clocks are not generated
create_generated_clock -name pclk [get_nets clocks393_i/dual_clock_pclk_i/clk1x_pre ]
create_generated_clock -name pclk2x [get_nets clocks393_i/dual_clock_pclk_i/clk2x_pre ]
#Sensor-synchronous clocks
create_generated_clock -name iclk0 [get_nets sensors393_i/sensor_channel_block\[0\].sensor_channel_i/sens_parallel12_i/ipclk_pre ]
create_generated_clock -name iclk2x0 [get_nets sensors393_i/sensor_channel_block\[0\].sensor_channel_i/sens_parallel12_i/ipclk2x_pre ]
create_generated_clock -name iclk1 [get_nets sensors393_i/sensor_channel_block\[1\].sensor_channel_i/sens_parallel12_i/ipclk_pre ]
create_generated_clock -name iclk2x1 [get_nets sensors393_i/sensor_channel_block\[1\].sensor_channel_i/sens_parallel12_i/ipclk2x_pre ]
create_generated_clock -name iclk2 [get_nets sensors393_i/sensor_channel_block\[2\].sensor_channel_i/sens_parallel12_i/ipclk_pre ]
create_generated_clock -name iclk2x2 [get_nets sensors393_i/sensor_channel_block\[2\].sensor_channel_i/sens_parallel12_i/ipclk2x_pre ]
create_generated_clock -name iclk3 [get_nets sensors393_i/sensor_channel_block\[3\].sensor_channel_i/sens_parallel12_i/ipclk_pre ]
create_generated_clock -name iclk2x3 [get_nets sensors393_i/sensor_channel_block\[3\].sensor_channel_i/sens_parallel12_i/ipclk2x_pre ]
# do not check timing between axi_aclk and other clocks. Code should provide correct asynchronous crossing of the clock boundary. # do not check timing between axi_aclk and other clocks. Code should provide correct asynchronous crossing of the clock boundary.
set_clock_groups -name ps_async_clock -asynchronous -group {axi_aclk} set_clock_groups -name ps_async_clock -asynchronous -group {axi_aclk}
# do not check timing between clk_axihp_pre and other clocks. Code should provide correct asynchronous crossing of the clock boundary. # do not check timing between clk_axihp_pre and other clocks. Code should provide correct asynchronous crossing of the clock boundary.
#set_clock_groups -name ps_async_clock_axihp -asynchronous -group {clk_axihp_pre}
set_clock_groups -name ps_async_clock_axihp -asynchronous -group {axihp_clk} set_clock_groups -name ps_async_clock_axihp -asynchronous -group {axihp_clk}
set_clock_groups -name compressor_clocks_xclk_xclk2x -asynchronous -group {xclk xclk2x}
set_clock_groups -name sensor_clocks_pclk_pclk2x -asynchronous -group {pclk pclk2x}
set_clock_groups -name sensor0_clocks_iclk_pclk2x -asynchronous -group {iclk0 iclk2x0}
set_clock_groups -name sensor1_clocks_iclk_pclk2x -asynchronous -group {iclk1 iclk2x1}
set_clock_groups -name sensor2_clocks_iclk_pclk2x -asynchronous -group {iclk2 iclk2x2}
set_clock_groups -name sensor3_clocks_iclk_pclk2x -asynchronous -group {iclk3 iclk2x3}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment