status_read.v 7.3 KB
Newer Older
1 2 3
/*******************************************************************************
 * Module: status_read
 * Date:2015-01-14  
4
 * Author: Andrey Filippov     
5 6 7 8 9 10 11 12 13 14
 * Description: Receives status read data (low bandwidth) from multiple
 * subsystems byte-serial, stores in axi-addressable memory
 * 8-bita ddress is received from the source module,
 * as well as another (optional) byte of sequence number (set in write command)
 * Sequence number (received first afther the address) is stored as a high byte,
 * lower bytes are the actual payload, starting from lower byte (not all 3 are
 * required. Single-bit responsen can be combined in the same byte with the
 * sequence number to use just 2-byte packets? 
 * TODO: add interrupt capabilities
 *
15
 * Copyright (c) 2015 Elphel, Inc.
16 17 18 19 20 21 22 23 24 25 26 27
 * status_read.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_read.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/> .
28 29 30 31 32 33
 *
 * Additional permission under GNU GPL version 3 section 7:
 * If you modify this Program, or any covered work, by linking or combining it
 * with independent modules provided by the FPGA vendor only (this permission
 * does not extend to any 3-rd party modules, "soft cores" or macros) under
 * different license terms solely for the purpose of generating binary "bitstream"
34
 * files and/or simulating the code, the copyright holders of this Program give
35 36
 * you the right to distribute the covered work without those independent modules
 * as long as the source code for them is available from the FPGA vendor free of
Andrey Filippov's avatar
Andrey Filippov committed
37
 * charge, and there is no dependence on any encrypted modules for simulating of
38 39 40
 * the combined code. This permission applies to you if the distributed code
 * contains all the components and scripts required to completely simulate it
 * with at least one of the Free Software programs.
41 42 43 44
 *******************************************************************************/
`timescale 1ns/1ps

module  status_read#(
45
    parameter STATUS_ADDR =           'h0800, // AXI read address of status read registers
46 47
    parameter STATUS_ADDR_MASK =      'h3c00, // AXI write address of status registers
    parameter AXI_RD_ADDR_BITS =      14,
48 49 50
    parameter integer STATUS_DEPTH=   8, // 256 cells, maybe just 16..64 are enough?
    parameter FPGA_VERSION =          32'h03930001
    )(
Andrey Filippov's avatar
Andrey Filippov committed
51 52 53
    input                        mrst, // @posedge mclk - sync reset
    input                        arst, // @posedge axi_clk - sync reset
    input                        clk,
54 55 56 57 58 59 60 61 62
    input                        axi_clk,   // common for read and write channels
    input [AXI_RD_ADDR_BITS-1:0] axird_pre_araddr,     // status read address, 1 cycle ahead of read data
    input                        axird_start_burst, // start of read burst, valid pre_araddr, save externally to control ext. dev_ready multiplexer
    input     [STATUS_DEPTH-1:0] axird_raddr, //   .raddr(read_in_progress?read_address[9:0]:10'h3ff),    // read address
    input                        axird_ren,   //      .ren(bram_reg_re_w) ,      // read port enable
    input                        axird_regen, //==axird_ren?? - remove?   .regen(bram_reg_re_w),        // output register enable
    output              [31:0]   axird_rdata,  // combinatorial multiplexed (add external register layer, modify axibram_read?)     .data_out(rdata[31:0]),       // data out
    output                       axird_selected, // axird_rdata contains cvalid data from this module, vcalid next after axird_start_burst
                                                 // so with ren/regen it may be delayed 1 more cycle
63 64 65 66
    input                  [7:0] ad,               // byte-serial status data from the sources
    input                        rq,               // request from sources to transfer status data
    output                       start             // acknowledge receiving of first byte (address), currently always ready
);
67
    localparam integer DATA_2DEPTH=(1<<STATUS_DEPTH)-1;
68
    reg  [31:0] ram [0:DATA_2DEPTH];
69
    reg         [STATUS_DEPTH-1:0] waddr;
70 71 72 73 74
    reg                          we;
    reg                  [31: 0] wdata;
    reg                          rq_r;
    reg                   [3:0]  dstb;
    
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
    wire                         select_w;
    reg                          select_r;
    reg                          select_d;
    
    wire                         rd;
    wire                         regen;
    reg                 [31:0]   axi_status_rdata; 
    reg                 [31:0]   axi_status_rdata_r;
    
    assign select_w = ((axird_pre_araddr ^ STATUS_ADDR) & STATUS_ADDR_MASK)==0;
    assign rd =        axird_ren   && select_r;
    assign regen =     axird_regen && select_d;
    
    
    
    
//    assign re= pre_stb && (((axi_pre_addr ^ STATUS_ADDR) & STATUS_ADDR_MASK) == 0);
//    assign raddr=axi_pre_addr[STATUS_DEPTH-1:0];
93
    assign start=rq && !rq_r;
94 95
    assign axird_rdata=axi_status_rdata_r;
    assign axird_selected = select_r; 
96
    initial begin
97 98 99 100
        ram [DATA_2DEPTH]   = FPGA_VERSION;
`ifdef HISPI
        ram [DATA_2DEPTH-1] = 1; //0 - parallel sensor, 1 - HiSPi sensor 
`endif         
101
    end
Andrey Filippov's avatar
Andrey Filippov committed
102 103
    always @ (posedge axi_clk) begin
        if      (arst)              select_r <= 0;
104 105 106 107 108 109 110 111
        else if (axird_start_burst) select_r <= select_w;
    end
    always @ (posedge axi_clk) begin
        if (rd)       axi_status_rdata <= ram[axird_raddr];
        if (regen)    axi_status_rdata_r <= axi_status_rdata;
        
        select_d <=   select_r;
    end
112
    
Andrey Filippov's avatar
Andrey Filippov committed
113
    always @ (posedge clk) begin
114
        
Andrey Filippov's avatar
Andrey Filippov committed
115 116
        if (mrst) rq_r <= 0;
        else      rq_r <= rq;
117
        
Andrey Filippov's avatar
Andrey Filippov committed
118
        if (mrst)       dstb <= 0;
119 120 121
        else if (!rq)   dstb <= 0;
        else            dstb <= {dstb[2:0],~rq_r};
        // byte 0 - address
Andrey Filippov's avatar
Andrey Filippov committed
122
        if (mrst)       waddr <= 0;
123
        else if (start) waddr <= ad[STATUS_DEPTH-1:0];
124 125 126 127
        
        // byte 1 - 2 payload bits and sequence number
        // 6 bits of the sequence number will go to bits 26.. 31
        // 2 bits (24,25) are payload status
Andrey Filippov's avatar
Andrey Filippov committed
128
        if (mrst)         wdata[31:24] <= 0;
129 130 131 132
        else if (start)   wdata[31:24] <= 0;
        else if (dstb[0]) wdata[31:24] <= ad;

        // byte 2 - payload bits 0..7 
Andrey Filippov's avatar
Andrey Filippov committed
133
        if (mrst)         wdata[ 7: 0] <= 0;
134 135 136 137
        else if (start)   wdata[ 7: 0] <= 0;
        else if (dstb[1]) wdata[ 7: 0] <= ad;
        
        // byte 3 - payload bits 8..15 
Andrey Filippov's avatar
Andrey Filippov committed
138
        if (mrst)         wdata[15: 8] <= 0;
139 140 141 142
        else if (start)   wdata[15: 8] <= 0;
        else if (dstb[2]) wdata[15: 8] <= ad;

        // byte 4 - payload bits 16..23 
Andrey Filippov's avatar
Andrey Filippov committed
143
        if (mrst)         wdata[23:16] <= 0;
144 145 146
        else if (start)   wdata[23:16] <= 0;
        else if (dstb[3]) wdata[23:16] <= ad;
        
Andrey Filippov's avatar
Andrey Filippov committed
147
        if (mrst)         we <= 0;
148 149 150 151
        else              we <= !rq && rq_r; 
    end
    
    always @ (posedge clk) begin
152
        if (we)     ram[waddr]  <= wdata; // shifted data here
153 154 155 156 157 158
    end
                             


endmodule