cmprs_afi_mux_status.v 9.74 KB
Newer Older
1 2 3
/*******************************************************************************
 * Module: cmprs_afi_mux_status
 * Date:2015-06-28  
4
 * Author: Andrey Filippov     
5 6 7 8 9 10
 * Description: prepare and send per-channel chunk pointer information as status
 * Using 4 consecutive locations. Each channel can provide one of the 4 pointers:
 * frame pointer in the write channel, current chunk pointer in the write channel
 * and the same for the write response channel (confirmed written to the system
 * memory
 *
11
 * Copyright (c) 2015 Elphel, Inc.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
 * cmprs_afi_mux_status.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.
 *
 *  cmprs_afi_mux_status.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  cmprs_afi_mux_status #(
28
    parameter CMPRS_AFIMUX_STATUS_REG_ADDR=     'h20,  //Uses 4 locations TODO: assign valid address
29 30 31
    parameter CMPRS_AFIMUX_WIDTH =              26, // maximal for status: currently only works with 26)
    parameter CMPRS_AFIMUX_CYCBITS =            3
 ) (
Andrey Filippov's avatar
Andrey Filippov committed
32
//    input                          rst,
33 34
    input                          hclk,         // global clock to run axi_hp @ 150MHz, shared by all compressor channels
    input                          mclk,         // for command/status
Andrey Filippov's avatar
Andrey Filippov committed
35 36
    input                          mrst,      // @posedge mclk, sync reset
    input                          hrst,      // @posedge xclk, sync reset
37 38 39 40 41 42 43 44 45 46 47 48 49 50
    // mclk domain
    input                   [15:0] cmd_data,     //  
    input                   [ 1:0] cmd_a,        //
    input                          status_we,    //
    input                          mode_we,      //
      
    output                   [7:0] status_ad,    // status address/data - up to 5 bytes: A - {seq,status[1:0]} - status[2:9] - status[10:17] - status[18:25]
    output                         status_rq,    // input request to send status downstream
    input                          status_start, // Acknowledge of the first status packet byte (address)
    // hclk domain
    input                          en,           // 1- enable, 0 - reset
    output reg               [3:0] chunk_ptr_ra, // full pointer address - {eof,wresp,chn[1:0]}
    input [CMPRS_AFIMUX_WIDTH-1:0] chunk_ptr_rd  // pointer data
);
51 52
   localparam MODE_WIDTH = 15;
    reg              [MODE_WIDTH-1:0] mode_data_mclk; // some bits unused
Andrey Filippov's avatar
Andrey Filippov committed
53 54 55
    wire                             mode_we_hclk;
    reg                        [7:0] mode_hclk;
    reg                        [1:0] index;
56 57 58
    reg   [CMPRS_AFIMUX_CYCBITS-1:0] cntr;
    reg     [CMPRS_AFIMUX_WIDTH-1:0] chunk_ptr_hclk;  // pointer data
    reg                        [1:0] chunk_chn_hclk;  // pointer channel
59
    
60
    reg [4 * CMPRS_AFIMUX_WIDTH-1:0] status_data;
61 62 63 64 65
    
    wire stb_w;
    reg  stb_r;
    wire stb_mclk;
    
66 67 68
    wire [31:0] ad;
    wire  [3:0] rq;
    wire  [3:0] start;
69 70 71
    
    assign stb_w = en && (cntr==0);
    always @ (posedge mclk) begin
72
        if (mode_we) mode_data_mclk <= cmd_data[MODE_WIDTH-1:0];
73 74 75 76 77 78 79 80 81
    end

    always @ (posedge hclk) begin
        if (mode_we_hclk) begin 
            if (mode_data_mclk[ 2]) mode_hclk[1:0] <= mode_data_mclk[ 1: 0];
            if (mode_data_mclk[ 6]) mode_hclk[3:2] <= mode_data_mclk[ 5: 4];
            if (mode_data_mclk[10]) mode_hclk[5:4] <= mode_data_mclk[ 9: 8];
            if (mode_data_mclk[14]) mode_hclk[7:6] <= mode_data_mclk[13:12];
            
82
            if (stb_mclk) status_data[chunk_chn_hclk * CMPRS_AFIMUX_WIDTH +: CMPRS_AFIMUX_WIDTH] <= chunk_ptr_hclk;
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
        end
        
        if (!en) {index,cntr} <= 0;
        else     {index,cntr} <= {index,cntr} + 1;
        
        if (stb_w) begin
            chunk_ptr_ra[1:0] <= index;
            case (index) 
                2'h0: chunk_ptr_ra[3:2] <= mode_hclk[1:0] ^ 1; // so 0 will be eof, internal
                2'h1: chunk_ptr_ra[3:2] <= mode_hclk[3:2] ^ 1;
                2'h2: chunk_ptr_ra[3:2] <= mode_hclk[5:4] ^ 1;
                2'h3: chunk_ptr_ra[3:2] <= mode_hclk[7:6] ^ 1;
            endcase
        end
        stb_r <= stb_w;
        if (stb_r) begin
            chunk_ptr_hclk <= {chunk_ptr_rd[23:0],chunk_ptr_rd[25:24]}; // bits 0,1 are sent to 25:24
            chunk_chn_hclk <= index;
        end
        
    end
    
Andrey Filippov's avatar
Andrey Filippov committed
105 106
    pulse_cross_clock mode_we_hclk_i (.rst(mrst), .src_clk(mclk), .dst_clk(hclk), .in_pulse(mode_we), .out_pulse(mode_we_hclk),.busy());
    pulse_cross_clock stb_mclk_i     (.rst(hrst), .src_clk(hclk), .dst_clk(mclk), .in_pulse(stb_r),   .out_pulse(stb_mclk),    .busy());
107
    status_router4 status_router4_i (
Andrey Filippov's avatar
Andrey Filippov committed
108
        .rst       (1'b0), // rst),            // input
109
        .clk       (mclk),           // input
Andrey Filippov's avatar
Andrey Filippov committed
110
        .srst      (mrst),            // input
111 112 113
        .db_in0    (ad[0 * 8 +: 8]), // input[7:0] 
        .rq_in0    (rq[0]),          // input
        .start_in0 (start[0]),       // output
114

115 116 117 118 119 120 121 122 123 124 125 126
        .db_in1    (ad[1 * 8 +: 8]), // input[7:0] 
        .rq_in1    (rq[1]),          // input
        .start_in1 (start[1]),       // output
        .db_in2    (ad[2 * 8 +: 8]), // input[7:0] 
        .rq_in2    (rq[2]),          // input
        .start_in2 (start[2]),       // output
        .db_in3    (ad[3 * 8 +: 8]), // input[7:0] 
        .rq_in3    (rq[3]),          // input
        .start_in3 (start[3]),       // output
        .db_out    (status_ad),      // output[7:0] 
        .rq_out    (status_rq),      // output
        .start_out (status_start)    // input
127 128 129 130 131 132
    );

    status_generate #(
        .STATUS_REG_ADDR  (CMPRS_AFIMUX_STATUS_REG_ADDR+0),
        .PAYLOAD_BITS     (CMPRS_AFIMUX_WIDTH)
    ) status_generate0_i (
Andrey Filippov's avatar
Andrey Filippov committed
133
        .rst     (1'b0),             //rst),                                                       // input
134
        .clk     (mclk),                                                      // input
Andrey Filippov's avatar
Andrey Filippov committed
135
        .srst    (mrst),                                                      // input
136 137 138 139 140 141
        .we      (status_we && (cmd_a==0)),                                   // input
        .wd      (cmd_data[7:0]),                                             // input[7:0] 
        .status  (status_data[0 * CMPRS_AFIMUX_WIDTH +: CMPRS_AFIMUX_WIDTH]), // input[25:0] 
        .ad      (ad[0 * 8 +: 8]),                                            // output[7:0] 
        .rq      (rq[0]),                                                     // output
        .start   (start[0])                                                   // input
142 143 144 145 146 147
    );

    status_generate #(
        .STATUS_REG_ADDR  (CMPRS_AFIMUX_STATUS_REG_ADDR+0),
        .PAYLOAD_BITS     (CMPRS_AFIMUX_WIDTH)
    ) status_generate1_i (
Andrey Filippov's avatar
Andrey Filippov committed
148
        .rst     (1'b0), //rst),                                                       // input
149
        .clk     (mclk),                                                      // input
Andrey Filippov's avatar
Andrey Filippov committed
150
        .srst    (mrst),                                                      // input
151 152 153 154 155 156
        .we      (status_we && (cmd_a==1)),                                   // input
        .wd      (cmd_data[7:0]),                                             // input[7:0] 
        .status  (status_data[1 * CMPRS_AFIMUX_WIDTH +: CMPRS_AFIMUX_WIDTH]), // input[25:0] 
        .ad      (ad[1 * 8 +: 8]),                                            // output[7:0] 
        .rq      (rq[1]),                                                     // output
        .start   (start[1])                                                   // input
157 158 159 160 161 162
    );

    status_generate #(
        .STATUS_REG_ADDR  (CMPRS_AFIMUX_STATUS_REG_ADDR+0),
        .PAYLOAD_BITS     (CMPRS_AFIMUX_WIDTH)
    ) status_generate2_i (
Andrey Filippov's avatar
Andrey Filippov committed
163
        .rst     (1'b0), //rst),                                                       // input
164
        .clk     (mclk),                                                      // input
Andrey Filippov's avatar
Andrey Filippov committed
165
        .srst    (mrst),                                                      // input
166 167 168 169 170 171
        .we      (status_we && (cmd_a==2)),                                   // input
        .wd      (cmd_data[7:0]),                                             // input[7:0] 
        .status  (status_data[2 * CMPRS_AFIMUX_WIDTH +: CMPRS_AFIMUX_WIDTH]), // input[25:0] 
        .ad      (ad[2 * 8 +: 8]),                                            // output[7:0] 
        .rq      (rq[2]),                                                     // output
        .start   (start[2])                                                   // input
172 173 174 175 176 177
    );

    status_generate #(
        .STATUS_REG_ADDR  (CMPRS_AFIMUX_STATUS_REG_ADDR+0),
        .PAYLOAD_BITS     (CMPRS_AFIMUX_WIDTH)
    ) status_generate3_i (
Andrey Filippov's avatar
Andrey Filippov committed
178
        .rst     (1'b0), // rst),                                                       // input
179
        .clk     (mclk),                                                      // input
Andrey Filippov's avatar
Andrey Filippov committed
180
        .srst    (mrst),                                                      // input
181 182 183 184 185 186
        .we      (status_we && (cmd_a==3)),                                   // input
        .wd      (cmd_data[7:0]),                                             // input[7:0] 
        .status  (status_data[3 * CMPRS_AFIMUX_WIDTH +: CMPRS_AFIMUX_WIDTH]), // input[25:0] 
        .ad      (ad[3 * 8 +: 8]),                                            // output[7:0] 
        .rq      (rq[3]),                                                     // output
        .start   (start[3])                                                   // input
187 188 189 190
    );

endmodule