thhor_crs/fpga/thhor_crs.v
2026-03-16 22:26:27 +01:00

235 lines
6.8 KiB
Verilog

module thhor_crs
(
input xclk,
input spi_ssel, spi_sck, spi_mosi,
output spi_miso,
// Barometer
output pt_MCLK, pt_SCLK, pt_Din,
input pt_Dout,
// ADCs
output [3:0] ADC_nCS, ADC_SCK, ADC_DIN,
input [3:0] ADC_DOUT,
// LVDS
output S_OUT, D_OUT,
input S_IN, D_IN,
// Spare Pins
inout [18:0] P25,
inout [7:0] P33
);
// no pll, the quarz is 32 MHz, as required.
wire mclk = xclk;
parameter ND=4;
///FIFO definitions
parameter NFIFO = 6;
wire [NFIFO:1] fifo_push, fifo_full;
wire [15:0] fifo[1:NFIFO], fsiz[1:NFIFO], fhma[1:NFIFO], fhva[1:NFIFO];
wire [3:1] fifo_halffull;
// packets that are generated on request only.
parameter FIFO_MUX = 1;
parameter FIFO_CNTR = 4;
parameter FIFO_BATE = 5;
parameter FIFO_HK = 6;
wire we, wp, re;
wire [13:0] wa;
wire [15:0] wd, rd, resets, confs;
wire stick;
wire [14:0] states, strobes;
wire [31:0] clock;
reg [15:0] fifo_mux, fsiz_mux, fhma_mux, fhva_mux;
reg fifo_mux_push;
assign fifo_push[FIFO_MUX] = fifo_mux_push;
assign fifo[FIFO_MUX] = fifo_mux;
assign fsiz[FIFO_MUX] = fsiz_mux;
assign fhma[FIFO_MUX] = fhma_mux;
assign fhva[FIFO_MUX] = fhva_mux;
assign fifo_full[NFIFO:4] = {(NFIFO-3){fifo_full[FIFO_MUX]}};
integer ii;
always @(posedge mclk)
begin
if (resets[4+FIFO_MUX])
fsiz_mux <= 0;
for (ii=4; ii<=NFIFO; ii=ii+1)
if (fifo_push[ii])
begin
fifo_mux <= fifo[ii];
fsiz_mux <= fsiz[ii];
fhma_mux <= fhma[ii];
fhva_mux <= fhva[ii];
end
fifo_mux_push <= |fifo_push[NFIFO:4];
end
frontend front
(.mclk(mclk),
.spi_ssel(~spi_ssel), .spi_sck(spi_sck), .spi_mosi(spi_mosi), .spi_miso(spi_miso),
.sclk(mclk), .ARxC(S_IN), .ARxD(D_IN), .ATxC(S_OUT), .ATxD(D_OUT),
.states(states), .strobes(strobes),
.we(we), .wp(wp), .wa(wa), .wd(wd), .re(re), .rd(rd),
.errors(), .stats(), .resets(resets), .confs(confs), .clock(),
.conf3(),
.fifo_push(fifo_push[3:1]), .fifo_full(fifo_full[3:1]),
.fifo_halffull(fifo_halffull),
.fifo1(fifo[1]), .fifo2(fifo[2]), .fifo3(fifo[3]),
.fsiz1(fsiz[1]), .fsiz2(fsiz[2]), .fsiz3(fsiz[3]),
.fhma1(fhma[1]), .fhma2(fhma[2]), .fhma3(fhma[3]),
.fhva1(fhva[1]), .fhva2(fhva[2]), .fhva3(fhva[3]),
.fsma1(64'b0), .fsma2(64'b0), .fsma3(64'b0),
.tick(stick) );
parameter NHIT = 3*ND + 1;
wire [NHIT-1:0] counter_hit;
parameter CNTR_ADDR = 'h 240;
wire read_counters = we & wa[13:4]==CNTR_ADDR[13:4];
assign fhma[FIFO_CNTR] = 16'h ffff;
nm_counters #(.N(NHIT)) counters
( .clk(mclk),
.clear(resets[1] | read_counters & wa[2] & (~fifo_full[FIFO_CNTR] | ~wa[3])),
.read(~fifo_full[FIFO_CNTR] & read_counters & wa[3]),
.read_size(wa[1:0]),
.clock(clock),
.hit(counter_hit),
.fifo_push(fifo_push[FIFO_CNTR]),
.fifo(fifo[FIFO_CNTR]),
.fifo_size(fsiz[FIFO_CNTR]),
.fifo_head(fhva[FIFO_CNTR]) );
parameter BATE_ADDR = 'h 0300; // … 'h 037f
wire we_bate = we & (wa[13:7] == BATE_ADDR[13:7]);
assign fhma[FIFO_BATE] = 'h ffff;
pressure #(.CLK96(32_000_000)) bate
( .clk96(mclk),
.MCLK(pt_MCLK),
.SCLK(pt_SCLK),
.Din(pt_Din),
.Dout(pt_Dout),
.we(we_bate),
.wa({1'b0, wa[6:0]}),
.fifos(fsiz[FIFO_BATE]),
.fifoh(fhva[FIFO_BATE]),
.fifoe(fifo_push[FIFO_BATE]),
.fifof(fifo_full[FIFO_BATE]),
.fifo(fifo[FIFO_BATE]) );
parameter HK_MAGIC = 16'h 5710;
parameter SA_MAGIC = 16'h 5714;
parameter EV_MAGIC = 16'h 5718;
assign fhva[FIFO_HK] = HK_MAGIC;
assign fhva[2] = EV_MAGIC;
assign fhva[3] = SA_MAGIC;
assign fhma[FIFO_HK] = 16'h ffff;
assign fhma[2] = 16'h ffff;
assign fhma[3] = 16'h ffff;
assign fsiz[FIFO_HK] = 8*ND;
assign fsiz[3] = 3*ND + 2;
thhor_core core
( .mclk(mclk),
.we(we), .wp(wp), .wa(wa), .wd(wd), .re(re), .rd(rd),
.confs(confs), .resets(resets),
.ax_states(states), .ax_strobes(strobes),
.fifo_e({fifo_push[3:2], fifo_push[FIFO_HK]}),
.fifo1(fifo[FIFO_HK]), .fifo2(fifo[2]), .fifo3(fifo[3]),
.afull({fifo_full[3:2], fifo_full[FIFO_HK]}),
.ev_psize(fsiz[2]),
.counter_hit(counter_hit), .stick(stick), .clock(clock),
.SCLK(ADC_SCK), .nCS(ADC_nCS), .DIN(ADC_DIN), .DOUT(ADC_DOUT) );
endmodule // thhor_crs
`ifdef SIMULATION
`timescale 1ns/1ps
`ifdef THHOR_CRS_TEST
module thhor_crs_test;
wire sclk, mosi, miso;
ssp_test spi(.sclk(sclk), .mosi(mosi), .miso(miso));
wire xclk;
wire [3:0] SCLK, nCS, DIN, DOUT;
stis_ana_jig #(.SLICES(1), .ND(4)) jig
( .xclk(xclk), .SCLK(SCLK[0]), .nCS(nCS[0]), .DIN(DIN[0]), .DOUT(DOUT));
always @(jig.send_command)
begin
if (jig.awp)
spi.cmdp(jig.awa, jig.awd);
else
spi.cmd(jig.awa);
-> jig.end_command;
end
wire pt_MCLK, pt_SCLK, pt_Din, pt_Dout;
ms5540c_sim bate(pt_MCLK, pt_SCLK, pt_Din, pt_Dout);
thhor_crs dut
(
.xclk(xclk),
.S_IN(1'b0),
.spi_ssel(1'b1), .spi_sck(sclk), .spi_mosi(mosi), .spi_miso(miso),
.pt_MCLK(pt_MCLK), .pt_SCLK(pt_SCLK), .pt_Din(pt_Din), .pt_Dout(pt_Dout),
.ADC_SCK(SCLK), .ADC_nCS(nCS), .ADC_DIN(DIN), .ADC_DOUT(DOUT)
);
initial
begin
$dumpfile("vcd/thhor_crs.fst");
$dumpvars(0);
#100 spi.verbose <= 2;
#100 spi.frame(0);
#4_000; // force a frame timeout
#100 spi.frame(0);
spi.rx_idle = 16'h 0000;
spi.cmdp(dut.front.SPIDE_ADDR, spi.rx_idle);
spi.cmdp(dut.front.HKSZ_ADDR, 0);
spi.cmd(dut.front.MRSTS_ADDR);
spi.cmdp(dut.front.MCONF_ADDR+3, 16'b 0000_1000_1111_1000);
spi.cmdp(dut.core.MISC_ADDR+11, 16'b 0000_0001_0000_1000);
spi.cmdp(dut.front.MRSTS_ADDR, 16'b 0000_0001_1111_1100);
jig.l1_conf;
jig.l2_conf;
jig.l3_conf;
spi.cmdp(dut.core.DORN_ADDR+'h8, 16'h 0e0e);
spi.cmdp(dut.core.DORN_ADDR+'h9, 16'h 000e);
spi.cmdp(dut.core.DORN_ADDR+'ha, 16'h 0000);
spi.cmdp(dut.core.DORN_ADDR+'hb, {8'b 01, 8'd 16});
spi.cmdp(dut.front. MCONF_ADDR+2, 16'b 0000_0000_0000_0001);
#30000;
jig.pulse(0,0,1);
jig.pulse(0, 'b 00_01, 0);
#20000 jig.pulse(0, 'b 01_11, 0);
#4000 jig.pulse(0, 'b 10_10, 0);
#50000 jig.pulse(0, 'b 00_01, 3);
#1000 jig.pulse(0, 'b 01_11, 1);
#20000 jig.pulse(0, 'b 10_10, 1);
repeat(100) spi.cmd(0);
spi.cmd(dut.CNTR_ADDR + 'b 1111);
repeat(100) spi.cmd(0);
spi.cmd(dut.BATE_ADDR + 'b 0111_1111);
repeat(1000) spi.cmd(0);
spi.cmdp(dut.core.MISC_ADDR+11, 16'b 0000_0000_0001_0000);
repeat(2000) spi.cmd(0);
#10000 $finish();
end
endmodule
`endif
`endif