`default_nettype none
/*
 *-------------------------------------------------------------
 *
 * top_astria.v
 * (adapted from user_proj_example from  caravel repo)
 *
 * Description:
 * Test circuits containing:
 * 1. Array of synthesized analog comparators for stochastic ADC (3 banks)
 * 2. Support circuits (shift register)
 * 3. LIF Neuron
 *
 * (1) Analog Comparator Bank 1, contains 32 comparators
 *      Name  : comp32
 *      Input : vcomp32_a, vcomp32_b --> GPIO analogio (24,25) (offset from dig)
 *      Output: [31:0] comp32out --> GPIO [31:0], 
 *                                   Logic Analyzer (LA) -> [31:0] la_data_out
 *                                   rdata / wbs_dat_o
 * (2) Analog Comparator Bank 2 & 3, contains 256 comparators each
 *      Name  : comp256_1, comp256_2
 *      Input : [1:0] vcomp256_a, [1:0] vcomp256_b --> GPIO analogio (26,27,28,29)
 *      Output: [1:0] comp256out --> GPIO (37,38),
 *                                   Logic Analyzer (LA) -> (32,33)
 *
 *-------------------------------------------------------------
 */

module top_astria #(
    parameter BITS = 32
)(
`ifdef USE_POWER_PINS
    inout vdda1,	// User area 1 3.3V supply
    inout vdda2,	// User area 2 3.3V supply
    inout vssa1,	// User area 1 analog ground
    inout vssa2,	// User area 2 analog ground
    inout vccd1,	// User area 1 1.8V supply
    inout vccd2,	// User area 2 1.8v supply
    inout vssd1,	// User area 1 digital ground
    inout vssd2,	// User area 2 digital ground
`endif

    // Wishbone Slave ports (WB MI A)
    input wb_clk_i,
    input wb_rst_i,
    input wbs_stb_i,
    input wbs_cyc_i,
    input wbs_we_i,
    input [3:0] wbs_sel_i,
    input [31:0] wbs_dat_i,
    input [31:0] wbs_adr_i,
    output wbs_ack_o,
    output [31:0] wbs_dat_o,

    // Logic Analyzer Signals
    input  [127:0] la_data_in,
    output [127:0] la_data_out,
    input  [127:0] la_oen,

    // IOs
    input  [`MPRJ_IO_PADS-1:0] io_in,
    output [`MPRJ_IO_PADS-1:0] io_out,
    output [`MPRJ_IO_PADS-1:0] io_oeb,

    // Analog (direct connection to GPIO pad---use with caution)
    // Note that analog I/O is not available on the 7 lowest-numbered
    // GPIO pads, and so the analog_io indexing is offset from the
    // GPIO indexing by 7.
    inout [`MPRJ_IO_PADS-8:0] analog_io    
);
    wire clk;
    wire rst;

    wire [`MPRJ_IO_PADS-1:0] io_in;
    wire [`MPRJ_IO_PADS-1:0] io_out;
    wire [`MPRJ_IO_PADS-1:0] io_oeb;

    wire [31:0] rdata; 
    wire [31:0] wdata;
    wire [BITS-1:0] comp32out;

    wire valid;
    wire [3:0] wstrb;
    wire [31:0] la_write;

    // WB MI A
    assign valid = wbs_cyc_i && wbs_stb_i; 
    assign wstrb = wbs_sel_i & {4{wbs_we_i}};
    assign wbs_dat_o = rdata;
    assign wdata = wbs_dat_i;

    // Comparator wires
    wire [1:0] comp256out;

    // IO
    assign io_out = {comp256out,comp32out[29:0]};   // cut 2 out from comp32
    assign io_oeb = {(`MPRJ_IO_PADS-1){rst}};

    // LA
    assign la_data_out = {{(127-BITS-2){1'b0}},comp256out,comp32out};

    // Assuming LA probes [63:32] are for controlling the count register  
    assign la_write = ~la_oen[65:34] & ~{BITS{valid}};

    // Assuming LA probes [67:66] are for controlling the clk & reset  
    assign clk = (~la_oen[66]) ? la_data_in[66]: wb_clk_i;
    assign rst = (~la_oen[67]) ? la_data_in[67]: wb_rst_i;


    stoch_adc_comp #(
        .BITS(BITS)
    ) stoch_adc_comp(
        .clk(clk),
        .reset(rst),
        .ready(wbs_ack_o),
        .valid(valid),
        .rdata(rdata),
        .wdata(wbs_dat_i),
        .wstrb(wstrb),
        .la_write(la_write),
        .la_input(la_data_in[63:32]),
        .vcomp32_a(analog_io[24]),
        .vcomp32_b(analog_io[25]),
        .vcomp256_a(analog_io[27:26]),
        .vcomp256_a(analog_io[29:28]),
        .comp32out(comp32out),
        .comp256out(comp256out)
    );

endmodule

module stoch_adc_comp #(
    parameter BITS = 32
)(
    input clk,
    input reset,
    input valid,
    input [3:0] wstrb,
    input [BITS-1:0] wdata,
    input [BITS-1:0] la_write,
    input [BITS-1:0] la_input,
    input vcomp32_a,
    input vcomp32_b,
    input [1:0] vcomp256_a,
    input [1:0] vcomp256_b,
    output ready,
    output [BITS-1:0] rdata,
    output [BITS-1:0] comp32out,
    output [1:0] comp256out
);
    reg ready;
    reg [BITS-1:0] rdata;

    // Comparator output registers
    reg [BITS-1:0] comp32out;    // Bank 1
    reg [255:0] comp256out1_reg; // Bank 2
    reg [255:0] comp256out2_reg; // Bank 3

    // Comparator output shift registers
    reg [255:0] comp256out1_sreg; // Bank 2
    reg [255:0] comp256out2_sreg; // Bank 3
    reg [7:0] counter_comp_sreg;

    // Take output from LSB of comp output shift reg
    assign comp256out[0] = comp256out1_sreg[0];
    assign comp256out[1] = comp256out2_sreg[0];

    // Dummy reg to take write operation from wishbone
    // Maybe useful later.
    reg [31:0] dummy;

    always @(posedge clk) begin
        if (reset) begin
            counter_comp_sreg <= 0;
            ready <= 0;
        end else begin
            ready <= 1'b0;
            
            if (~|la_write) begin
                // shift outputs
                counter_comp_sreg <= counter_comp_sreg + 1;
                comp256out1_sreg <= {{1'b0},comp256out1_sreg[31:1]};
                comp256out2_sreg <= {{1'b0},comp256out2_sreg[31:1]};
            end

            if (valid && !ready) begin
                ready <= 1'b1;
                rdata <= comp32out;
                if (wstrb[0]) dummy[7:0]   <= wdata[7:0];
                if (wstrb[1]) dummy[15:8]  <= wdata[15:8];
                if (wstrb[2]) dummy[23:16] <= wdata[23:16];
                if (wstrb[3]) dummy[31:24] <= wdata[31:24];
            end

            if (counter_comp_sreg == 0) begin
                comp256out1_sreg <= comp256out1_reg;
                comp256out2_sreg <= comp256out2_reg;
            end
        end
    end
/*
    genvar i;
    generate 
        for(i=0; i<BITS; i=i+1) begin
          always @(posedge clk) begin
              if (la_write[i]) count[i] <= la_input[i];
          end
        end
    endgenerate
*/
    genvar j;
    generate 
        for(j=0; j<32; j=j+1) begin
            synthcomp comp32(clk, vcomp32_a, vcomp32_b, comp32out[j]);
        end
    endgenerate

    genvar k;
    generate 
        for(k=0; k<256; k=k+1) begin
            synthcomp comp256_1(clk, vcomp256_a[0], vcomp256_b[0], comp256out1_reg[k]);
        end
    endgenerate

    genvar l;
    generate 
        for(l=0; l<256; l=l+1) begin
            synthcomp comp256_2(clk, vcomp256_a[1], vcomp256_b[1], comp256out1_reg[l]);
        end
    endgenerate

endmodule

/* ----------------------
Synthesizable analog clocked comparator based on Sky130 NOR4 cells

Similar principle to NAND3 based design reported in:
[1] S. Weaver, B. Hershberg, and U.-K. Moon, 
"Digitally Synthesized Stochastic Flash ADC Using Only Standard Digital Cells," 
IEEE Trans. Circuits Syst. I Regul. Pap., vol. 61, no. 1, pp. 84–91, Jan. 2014, 
doi: 10.1109/TCSI.2013.2268571.
-------------------------
*/
module synthcomp (
    input clk,
    input v_a,
    input v_b,
    output comp_out);

wire qa, qb, qx;

sky130_fd_sc_hd__nor4_1 X_NOR1 (qa, v_a, qb, qb, clk);
sky130_fd_sc_hd__nor4_1 X_NOR2 (qb, v_b, qa, qa, clk);
sky130_fd_sc_hd__nor4_1 X_NOR3 (comp_out, qa, qa, qx, qx);
sky130_fd_sc_hd__nor4_1 X_NOR4 (qx, qb, qb, comp_out, comp_out);

endmodule

`default_nettype wire
