`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 |