adc_driver seems to be working to original spec, now to shift the slave select back a few cycles

This commit is contained in:
Kelvin Ly 2020-01-07 09:02:04 -05:00
parent 5f2364b5cf
commit 9b35a04234
5 changed files with 9281 additions and 21 deletions

View File

@ -3,16 +3,24 @@ module adc_driver(
input rstn,
input adc_so,
output reg adc_si,
output reg adc_ss,
reg adc_sck,
output adc_si,
output adc_ss,
output adc_sck,
output reg [1:0] channel,
output reg [11:0] adc_val,
output [1:0] channel,
output [11:0] adc_val,
output reg vld,
input ack
);
reg [1:0] channel_ff = 0;
reg [11:0] adc_val_ff = 0;
reg vld_ff = 0;
assign channel = channel_ff;
assign adc_val = adc_val_ff;
assign vld = vld_ff;
reg [2:0] sck_strobe = 0;
wire strobe = &sck_strobe;
@ -38,11 +46,16 @@ reg sck_next;
reg ss_next;
reg si_next;
reg adc_si_ff = 1;
reg adc_ss_ff = 1;
reg adc_sck_ff = 1;
assign adc_si = adc_si_ff;
assign adc_ss = adc_ss_ff;
assign adc_sck = adc_sck_ff;
wire [15:0] config_word;
wire config_bit;
assign config_bit = {
assign config_word = {
1'b0, // ADC Mode Control
4'b0100, // Standard_Ext
4'b0011, // Up to AIN3
@ -50,8 +63,9 @@ assign config_bit = {
2'b00, // normal PM mode
1'b1, // include channel number in output
1'b0, // SWCNV enable, not used in external clock mode
1'b0, // reserved
}[15-bit_pos];
1'b0 // reserved
};
assign config_bit = config_word[15-bit_pos];
always @* begin
state_next = state;
@ -68,7 +82,7 @@ always @* begin
ss_next = adc_ss;
sck_next = adc_sck;
if (sck_strobe) begin
if (strobe) begin
case (state)
INIT: begin
ss_next = 0;
@ -102,23 +116,20 @@ always @* begin
si_next = 0;
sck_next = ~adc_sck;
// update bit pos state on the falling edge
// update bit pos state on the rising edge
// shift in data as well
if (adc_sck) begin
if (~adc_sck) begin
bit_pos_next = bit_pos + 1;
so_ff_next = {so_ff[14:0], adc_si};
so_ff_next = {so_ff[14:0], adc_so};
// after reading the last bit
// deassert ss so it can be reasserted on the next rising edge
if (bit_pos == 15) begin
ss_next = 1;
write_out = 1;
end
end
// write the data out on the rising edge after the overflow
if (~adc_sck & (bit_pos == 0)) begin
write_out = 1;
end
end
endcase
end
@ -135,18 +146,18 @@ always @(posedge clk) begin
bit_pos <= bit_pos_next;
adc_sck_ff <= sck_next;
adc_ss <= ss_next;
adc_si <= si_next;
adc_ss_ff <= ss_next;
adc_si_ff <= si_next;
so_ff <= so_ff_next;
// write the data out when write_out is asserted
if (write_out) begin
{adc_channel, adc_val} <= so_ff[13:0];
vld <= 1;
{channel_ff, adc_val_ff} <= so_ff_next[13:0];
vld_ff <= 1;
end
// deassert vld when the data is acknowledged
if (ack)
vld <= 0;
vld_ff <= 0;
end
endmodule

563
rtl/tb/a.out Executable file
View File

@ -0,0 +1,563 @@
#! /usr/bin/vvp
:ivl_version "10.3 (stable)";
:ivl_delay_selection "TYPICAL";
:vpi_time_precision - 8;
:vpi_module "system";
:vpi_module "vhdl_sys";
:vpi_module "v2005_math";
:vpi_module "va_math";
:vpi_module "v2009";
S_0x55c406b87500 .scope module, "top" "top" 2 3;
.timescale -8 -8;
v0x55c406bd3a20_0 .var "ack", 0 0;
v0x55c406bd3ae0 .array/i "adc_out", 0 3, 31 0;
v0x55c406bd3b80_0 .var/i "adc_pos", 31 0;
v0x55c406bd3c40_0 .net "adc_sck", 0 0, L_0x55c406bd4e50; 1 drivers
v0x55c406bd3d10_0 .net "adc_si", 0 0, L_0x55c406bd4ca0; 1 drivers
v0x55c406bd3db0_0 .var "adc_so", 0 0;
v0x55c406bd3e80_0 .net "adc_ss", 0 0, L_0x55c406bd4d90; 1 drivers
v0x55c406bd3f50_0 .net "adc_val", 11 0, L_0x55c406ba6030; 1 drivers
v0x55c406bd4020_0 .var/i "bit_pos", 31 0;
v0x55c406bd40c0_0 .net "channel", 1 0, L_0x55c406ba6120; 1 drivers
v0x55c406bd4190_0 .var/i "channel_num", 31 0;
v0x55c406bd4230_0 .var "clk", 0 0;
v0x55c406bd4300_0 .var/i "configdata", 31 0;
v0x55c406bd43c0_0 .var "configured", 0 0;
v0x55c406bd4480_0 .var "enabled", 0 0;
v0x55c406bd4540_0 .var/i "i", 31 0;
v0x55c406bd4620_0 .var "out", 15 0;
v0x55c406bd4700_0 .var "rstn", 0 0;
v0x55c406bd47d0_0 .var "sck_old", 0 0;
v0x55c406bd4870_0 .var "ss_old", 0 0;
v0x55c406bd4930_0 .var/i "tosend", 31 0;
v0x55c406bd4a10_0 .net "vld", 0 0, L_0x55c406ba5f40; 1 drivers
E_0x55c406ba5370 .event edge, v0x55c406bd3b80_0;
S_0x55c406b5f260 .scope module, "dut" "adc_driver" 2 21, 3 1 0, S_0x55c406b87500;
.timescale -8 -8;
.port_info 0 /INPUT 1 "clk"
.port_info 1 /INPUT 1 "rstn"
.port_info 2 /INPUT 1 "adc_so"
.port_info 3 /OUTPUT 1 "adc_si"
.port_info 4 /OUTPUT 1 "adc_ss"
.port_info 5 /OUTPUT 1 "adc_sck"
.port_info 6 /OUTPUT 2 "channel"
.port_info 7 /OUTPUT 12 "adc_val"
.port_info 8 /OUTPUT 1 "vld"
.port_info 9 /INPUT 1 "ack"
P_0x55c406b87140 .param/l "ADC" 1 3 34, +C4<00000000000000000000000000000010>;
P_0x55c406b87180 .param/l "CONFIG" 1 3 34, +C4<00000000000000000000000000000001>;
P_0x55c406b871c0 .param/l "INIT" 1 3 34, +C4<00000000000000000000000000000000>;
L_0x55c406ba6120 .functor BUFZ 2, v0x55c406bd2930_0, C4<00>, C4<00>, C4<00>;
L_0x55c406ba6030 .functor BUFZ 12, v0x55c406bd25b0_0, C4<000000000000>, C4<000000000000>, C4<000000000000>;
L_0x55c406ba5f40 .functor BUFZ 1, v0x55c406bd3550_0, C4<0>, C4<0>, C4<0>;
L_0x55c406bd4ca0 .functor BUFZ 1, v0x55c406bd21d0_0, C4<0>, C4<0>, C4<0>;
L_0x55c406bd4d90 .functor BUFZ 1, v0x55c406bd2410_0, C4<0>, C4<0>, C4<0>;
L_0x55c406bd4e50 .functor BUFZ 1, v0x55c406bd2050_0, C4<0>, C4<0>, C4<0>;
L_0x7ff03e59d060 .functor BUFT 1, C4<00000000000000000000000000001111>, C4<0>, C4<0>, C4<0>;
v0x55c406bb29b0_0 .net/2u *"_s16", 31 0, L_0x7ff03e59d060; 1 drivers
v0x55c406b8a8d0_0 .net *"_s18", 31 0, L_0x55c406be4fc0; 1 drivers
L_0x7ff03e59d0a8 .functor BUFT 1, C4<0000000000000000000000000000>, C4<0>, C4<0>, C4<0>;
v0x55c406bd1ce0_0 .net *"_s21", 27 0, L_0x7ff03e59d0a8; 1 drivers
v0x55c406bd1da0_0 .net *"_s22", 31 0, L_0x55c406be5140; 1 drivers
v0x55c406bd1e80_0 .net "ack", 0 0, v0x55c406bd3a20_0; 1 drivers
v0x55c406bd1f90_0 .net "adc_sck", 0 0, L_0x55c406bd4e50; alias, 1 drivers
v0x55c406bd2050_0 .var "adc_sck_ff", 0 0;
v0x55c406bd2110_0 .net "adc_si", 0 0, L_0x55c406bd4ca0; alias, 1 drivers
v0x55c406bd21d0_0 .var "adc_si_ff", 0 0;
v0x55c406bd2290_0 .net "adc_so", 0 0, v0x55c406bd3db0_0; 1 drivers
v0x55c406bd2350_0 .net "adc_ss", 0 0, L_0x55c406bd4d90; alias, 1 drivers
v0x55c406bd2410_0 .var "adc_ss_ff", 0 0;
v0x55c406bd24d0_0 .net "adc_val", 11 0, L_0x55c406ba6030; alias, 1 drivers
v0x55c406bd25b0_0 .var "adc_val_ff", 11 0;
v0x55c406bd2690_0 .var "bit_pos", 3 0;
v0x55c406bd2770_0 .var "bit_pos_next", 3 0;
v0x55c406bd2850_0 .net "channel", 1 0, L_0x55c406ba6120; alias, 1 drivers
v0x55c406bd2930_0 .var "channel_ff", 1 0;
v0x55c406bd2a10_0 .net "clk", 0 0, v0x55c406bd4230_0; 1 drivers
v0x55c406bd2ad0_0 .net "config_bit", 0 0, L_0x55c406be5320; 1 drivers
L_0x7ff03e59d018 .functor BUFT 1, C4<0010000110100100>, C4<0>, C4<0>, C4<0>;
v0x55c406bd2b90_0 .net "config_word", 15 0, L_0x7ff03e59d018; 1 drivers
v0x55c406bd2c70_0 .net "rstn", 0 0, v0x55c406bd4700_0; 1 drivers
v0x55c406bd2d30_0 .var "sck_next", 0 0;
v0x55c406bd2df0_0 .var "sck_strobe", 2 0;
v0x55c406bd2ed0_0 .var "si_next", 0 0;
v0x55c406bd2f90_0 .var "so_ff", 15 0;
v0x55c406bd3070_0 .var "so_ff_next", 15 0;
v0x55c406bd3150_0 .var "ss_next", 0 0;
v0x55c406bd3210_0 .var "state", 1 0;
v0x55c406bd32f0_0 .var "state_next", 1 0;
v0x55c406bd33d0_0 .net "strobe", 0 0, L_0x55c406bd4ba0; 1 drivers
v0x55c406bd3490_0 .net "vld", 0 0, L_0x55c406ba5f40; alias, 1 drivers
v0x55c406bd3550_0 .var "vld_ff", 0 0;
v0x55c406bd3820_0 .var "write_out", 0 0;
E_0x55c406ba3660 .event posedge, v0x55c406bd2a10_0;
E_0x55c406ba4480/0 .event edge, v0x55c406bd3210_0, v0x55c406bd2690_0, v0x55c406bd2f90_0, v0x55c406bd2c70_0;
E_0x55c406ba4480/1 .event edge, v0x55c406bd2110_0, v0x55c406bd2350_0, v0x55c406bd1f90_0, v0x55c406bd33d0_0;
E_0x55c406ba4480/2 .event edge, v0x55c406bd2ad0_0, v0x55c406bd2290_0;
E_0x55c406ba4480 .event/or E_0x55c406ba4480/0, E_0x55c406ba4480/1, E_0x55c406ba4480/2;
L_0x55c406bd4ba0 .reduce/and v0x55c406bd2df0_0;
L_0x55c406be4fc0 .concat [ 4 28 0 0], v0x55c406bd2690_0, L_0x7ff03e59d0a8;
L_0x55c406be5140 .arith/sub 32, L_0x7ff03e59d060, L_0x55c406be4fc0;
L_0x55c406be5320 .part/v L_0x7ff03e59d018, L_0x55c406be5140, 1;
.scope S_0x55c406b5f260;
T_0 ;
%pushi/vec4 0, 0, 2;
%store/vec4 v0x55c406bd2930_0, 0, 2;
%pushi/vec4 0, 0, 12;
%store/vec4 v0x55c406bd25b0_0, 0, 12;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x55c406bd3550_0, 0, 1;
%pushi/vec4 0, 0, 3;
%store/vec4 v0x55c406bd2df0_0, 0, 3;
%pushi/vec4 0, 0, 2;
%store/vec4 v0x55c406bd3210_0, 0, 2;
%pushi/vec4 0, 0, 4;
%store/vec4 v0x55c406bd2690_0, 0, 4;
%pushi/vec4 0, 0, 16;
%store/vec4 v0x55c406bd2f90_0, 0, 16;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd21d0_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd2410_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd2050_0, 0, 1;
%end;
.thread T_0, $init;
.scope S_0x55c406b5f260;
T_1 ;
%wait E_0x55c406ba3660;
%load/vec4 v0x55c406bd2c70_0;
%flag_set/vec4 8;
%jmp/0xz T_1.0, 8;
%load/vec4 v0x55c406bd2df0_0;
%addi 1, 0, 3;
%assign/vec4 v0x55c406bd2df0_0, 0;
%jmp T_1.1;
T_1.0 ;
%pushi/vec4 0, 0, 3;
%assign/vec4 v0x55c406bd2df0_0, 0;
T_1.1 ;
%jmp T_1;
.thread T_1;
.scope S_0x55c406b5f260;
T_2 ;
%wait E_0x55c406ba4480;
%load/vec4 v0x55c406bd3210_0;
%store/vec4 v0x55c406bd32f0_0, 0, 2;
%load/vec4 v0x55c406bd2690_0;
%store/vec4 v0x55c406bd2770_0, 0, 4;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x55c406bd3820_0, 0, 1;
%load/vec4 v0x55c406bd2f90_0;
%store/vec4 v0x55c406bd3070_0, 0, 16;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd2d30_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd3150_0, 0, 1;
%load/vec4 v0x55c406bd2c70_0;
%flag_set/vec4 8;
%jmp/0xz T_2.0, 8;
%load/vec4 v0x55c406bd2110_0;
%store/vec4 v0x55c406bd2ed0_0, 0, 1;
%load/vec4 v0x55c406bd2350_0;
%store/vec4 v0x55c406bd3150_0, 0, 1;
%load/vec4 v0x55c406bd1f90_0;
%store/vec4 v0x55c406bd2d30_0, 0, 1;
%load/vec4 v0x55c406bd33d0_0;
%flag_set/vec4 8;
%jmp/0xz T_2.2, 8;
%load/vec4 v0x55c406bd3210_0;
%dup/vec4;
%pushi/vec4 0, 0, 2;
%cmp/u;
%jmp/1 T_2.4, 6;
%dup/vec4;
%pushi/vec4 1, 0, 2;
%cmp/u;
%jmp/1 T_2.5, 6;
%dup/vec4;
%pushi/vec4 2, 0, 2;
%cmp/u;
%jmp/1 T_2.6, 6;
%jmp T_2.7;
T_2.4 ;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x55c406bd3150_0, 0, 1;
%pushi/vec4 1, 0, 2;
%store/vec4 v0x55c406bd32f0_0, 0, 2;
%pushi/vec4 0, 0, 4;
%store/vec4 v0x55c406bd2770_0, 0, 4;
%jmp T_2.7;
T_2.5 ;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x55c406bd3150_0, 0, 1;
%load/vec4 v0x55c406bd1f90_0;
%inv;
%store/vec4 v0x55c406bd2d30_0, 0, 1;
%load/vec4 v0x55c406bd1f90_0;
%flag_set/vec4 8;
%jmp/0xz T_2.8, 8;
%load/vec4 v0x55c406bd2690_0;
%addi 1, 0, 4;
%store/vec4 v0x55c406bd2770_0, 0, 4;
%load/vec4 v0x55c406bd2ad0_0;
%store/vec4 v0x55c406bd2ed0_0, 0, 1;
%load/vec4 v0x55c406bd2690_0;
%pad/u 32;
%cmpi/e 15, 0, 32;
%jmp/0xz T_2.10, 4;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd3150_0, 0, 1;
T_2.10 ;
T_2.8 ;
%load/vec4 v0x55c406bd1f90_0;
%inv;
%load/vec4 v0x55c406bd2690_0;
%pad/u 32;
%pushi/vec4 0, 0, 32;
%cmp/e;
%flag_get/vec4 4;
%and;
%flag_set/vec4 8;
%jmp/0xz T_2.12, 8;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x55c406bd3150_0, 0, 1;
%pushi/vec4 2, 0, 2;
%store/vec4 v0x55c406bd32f0_0, 0, 2;
T_2.12 ;
%jmp T_2.7;
T_2.6 ;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x55c406bd3150_0, 0, 1;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x55c406bd2ed0_0, 0, 1;
%load/vec4 v0x55c406bd1f90_0;
%inv;
%store/vec4 v0x55c406bd2d30_0, 0, 1;
%load/vec4 v0x55c406bd1f90_0;
%inv;
%flag_set/vec4 8;
%jmp/0xz T_2.14, 8;
%load/vec4 v0x55c406bd2690_0;
%addi 1, 0, 4;
%store/vec4 v0x55c406bd2770_0, 0, 4;
%load/vec4 v0x55c406bd2f90_0;
%parti/s 15, 0, 2;
%load/vec4 v0x55c406bd2290_0;
%concat/vec4; draw_concat_vec4
%store/vec4 v0x55c406bd3070_0, 0, 16;
%load/vec4 v0x55c406bd2690_0;
%pad/u 32;
%cmpi/e 15, 0, 32;
%jmp/0xz T_2.16, 4;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd3150_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd3820_0, 0, 1;
T_2.16 ;
T_2.14 ;
%jmp T_2.7;
T_2.7 ;
%pop/vec4 1;
T_2.2 ;
%jmp T_2.1;
T_2.0 ;
%pushi/vec4 0, 0, 2;
%store/vec4 v0x55c406bd32f0_0, 0, 2;
%pushi/vec4 0, 0, 4;
%store/vec4 v0x55c406bd2770_0, 0, 4;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd2d30_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd3150_0, 0, 1;
T_2.1 ;
%jmp T_2;
.thread T_2, $push;
.scope S_0x55c406b5f260;
T_3 ;
%wait E_0x55c406ba3660;
%load/vec4 v0x55c406bd32f0_0;
%assign/vec4 v0x55c406bd3210_0, 0;
%load/vec4 v0x55c406bd2770_0;
%assign/vec4 v0x55c406bd2690_0, 0;
%load/vec4 v0x55c406bd2d30_0;
%assign/vec4 v0x55c406bd2050_0, 0;
%load/vec4 v0x55c406bd3150_0;
%assign/vec4 v0x55c406bd2410_0, 0;
%load/vec4 v0x55c406bd2ed0_0;
%assign/vec4 v0x55c406bd21d0_0, 0;
%load/vec4 v0x55c406bd3070_0;
%assign/vec4 v0x55c406bd2f90_0, 0;
%load/vec4 v0x55c406bd3820_0;
%flag_set/vec4 8;
%jmp/0xz T_3.0, 8;
%load/vec4 v0x55c406bd3070_0;
%parti/s 14, 0, 2;
%split/vec4 12;
%assign/vec4 v0x55c406bd25b0_0, 0;
%assign/vec4 v0x55c406bd2930_0, 0;
%pushi/vec4 1, 0, 1;
%assign/vec4 v0x55c406bd3550_0, 0;
T_3.0 ;
%load/vec4 v0x55c406bd1e80_0;
%flag_set/vec4 8;
%jmp/0xz T_3.2, 8;
%pushi/vec4 0, 0, 1;
%assign/vec4 v0x55c406bd3550_0, 0;
T_3.2 ;
%jmp T_3;
.thread T_3;
.scope S_0x55c406b87500;
T_4 ;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x55c406bd4230_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd4700_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd3db0_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd47d0_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd4870_0, 0, 1;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x55c406bd3a20_0, 0, 1;
%end;
.thread T_4, $init;
.scope S_0x55c406b87500;
T_5 ;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x55c406bd4230_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd4700_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd3db0_0, 0, 1;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd47d0_0, 0, 1;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x55c406bd43c0_0, 0, 1;
%pushi/vec4 0, 0, 16;
%store/vec4 v0x55c406bd4620_0, 0, 16;
%vpi_call/w 2 48 "$dumpfile", "adc_driver_tb.vcd" {0 0 0};
%vpi_call/w 2 49 "$dumpvars" {0 0 0};
%end;
.thread T_5;
.scope S_0x55c406b87500;
T_6 ;
%delay 2, 0;
%load/vec4 v0x55c406bd4230_0;
%nor/r;
%store/vec4 v0x55c406bd4230_0, 0, 1;
%jmp T_6;
.thread T_6;
.scope S_0x55c406b87500;
T_7 ;
%pushi/vec4 0, 0, 32;
%store/vec4 v0x55c406bd4020_0, 0, 32;
%pushi/vec4 0, 0, 32;
%store/vec4 v0x55c406bd4190_0, 0, 32;
%pushi/vec4 0, 0, 32;
%store/vec4 v0x55c406bd4930_0, 0, 32;
%pushi/vec4 0, 0, 1;
%store/vec4 v0x55c406bd4480_0, 0, 1;
%pushi/vec4 0, 0, 32;
%store/vec4 v0x55c406bd4300_0, 0, 32;
%pushi/vec4 0, 0, 32;
%store/vec4 v0x55c406bd3b80_0, 0, 32;
%pushi/vec4 1, 0, 1;
%store/vec4 v0x55c406bd3db0_0, 0, 1;
%pushi/vec4 0, 0, 32;
%store/vec4 v0x55c406bd4540_0, 0, 32;
T_7.0 ;
%load/vec4 v0x55c406bd4540_0;
%cmpi/s 4, 0, 32;
%jmp/0xz T_7.1, 5;
%pushi/vec4 0, 0, 32;
%ix/getv/s 4, v0x55c406bd4540_0;
%store/vec4a v0x55c406bd3ae0, 4, 0;
%load/vec4 v0x55c406bd4540_0;
%pushi/vec4 1, 0, 32;
%add;
%store/vec4 v0x55c406bd4540_0, 0, 32;
%jmp T_7.0;
T_7.1 ;
%end;
.thread T_7;
.scope S_0x55c406b87500;
T_8 ;
%wait E_0x55c406ba5370;
%load/vec4 v0x55c406bd3b80_0;
%parti/s 2, 0, 2;
%dup/vec4;
%pushi/vec4 0, 0, 2;
%cmp/u;
%jmp/1 T_8.0, 6;
%dup/vec4;
%pushi/vec4 1, 0, 2;
%cmp/u;
%jmp/1 T_8.1, 6;
%dup/vec4;
%pushi/vec4 2, 0, 2;
%cmp/u;
%jmp/1 T_8.2, 6;
%dup/vec4;
%pushi/vec4 3, 0, 2;
%cmp/u;
%jmp/1 T_8.3, 6;
%jmp T_8.4;
T_8.0 ;
%pushi/vec4 511, 0, 16;
%store/vec4 v0x55c406bd4620_0, 0, 16;
%jmp T_8.4;
T_8.1 ;
%pushi/vec4 8191, 0, 16;
%store/vec4 v0x55c406bd4620_0, 0, 16;
%jmp T_8.4;
T_8.2 ;
%pushi/vec4 11754, 0, 16;
%store/vec4 v0x55c406bd4620_0, 0, 16;
%jmp T_8.4;
T_8.3 ;
%pushi/vec4 15535, 0, 16;
%store/vec4 v0x55c406bd4620_0, 0, 16;
%jmp T_8.4;
T_8.4 ;
%pop/vec4 1;
%jmp T_8;
.thread T_8, $push;
.scope S_0x55c406b87500;
T_9 ;
%wait E_0x55c406ba3660;
%load/vec4 v0x55c406bd3e80_0;
%inv;
%load/vec4 v0x55c406bd4870_0;
%and;
%flag_set/vec4 8;
%jmp/0xz T_9.0, 8;
%pushi/vec4 1, 0, 1;
%assign/vec4 v0x55c406bd4480_0, 0;
%pushi/vec4 0, 0, 32;
%assign/vec4 v0x55c406bd4020_0, 0;
T_9.0 ;
%load/vec4 v0x55c406bd4480_0;
%flag_set/vec4 8;
%jmp/0xz T_9.2, 8;
%load/vec4 v0x55c406bd43c0_0;
%nor/r;
%flag_set/vec4 8;
%jmp/0xz T_9.4, 8;
%load/vec4 v0x55c406bd47d0_0;
%inv;
%load/vec4 v0x55c406bd3c40_0;
%and;
%flag_set/vec4 8;
%jmp/0xz T_9.6, 8;
%load/vec4 v0x55c406bd4300_0;
%ix/load 4, 1, 0;
%flag_set/imm 4, 0;
%shiftl 4;
%load/vec4 v0x55c406bd3d10_0;
%pad/u 32;
%or;
%assign/vec4 v0x55c406bd4300_0, 0;
%pushi/vec4 15, 0, 32;
%load/vec4 v0x55c406bd4020_0;
%cmp/s;
%flag_or 5, 4;
%jmp/0xz T_9.8, 5;
%pushi/vec4 1, 0, 1;
%assign/vec4 v0x55c406bd43c0_0, 0;
%pushi/vec4 0, 0, 32;
%assign/vec4 v0x55c406bd4020_0, 0;
%jmp T_9.9;
T_9.8 ;
%load/vec4 v0x55c406bd4020_0;
%addi 1, 0, 32;
%assign/vec4 v0x55c406bd4020_0, 0;
T_9.9 ;
T_9.6 ;
%jmp T_9.5;
T_9.4 ;
%load/vec4 v0x55c406bd47d0_0;
%inv;
%load/vec4 v0x55c406bd3c40_0;
%and;
%flag_set/vec4 8;
%jmp/0xz T_9.10, 8;
T_9.10 ;
%load/vec4 v0x55c406bd47d0_0;
%load/vec4 v0x55c406bd3c40_0;
%inv;
%and;
%flag_set/vec4 8;
%jmp/0xz T_9.12, 8;
%pushi/vec4 15, 0, 32;
%load/vec4 v0x55c406bd4020_0;
%cmp/s;
%flag_or 5, 4;
%jmp/0xz T_9.14, 5;
%pushi/vec4 0, 0, 32;
%assign/vec4 v0x55c406bd4020_0, 0;
%jmp T_9.15;
T_9.14 ;
%load/vec4 v0x55c406bd4020_0;
%addi 1, 0, 32;
%assign/vec4 v0x55c406bd4020_0, 0;
T_9.15 ;
%load/vec4 v0x55c406bd4620_0;
%pushi/vec4 15, 0, 32;
%load/vec4 v0x55c406bd4020_0;
%sub;
%part/s 1;
%assign/vec4 v0x55c406bd3db0_0, 0;
T_9.12 ;
T_9.5 ;
T_9.2 ;
%load/vec4 v0x55c406bd4a10_0;
%load/vec4 v0x55c406bd43c0_0;
%and;
%load/vec4 v0x55c406bd3a20_0;
%inv;
%and;
%flag_set/vec4 8;
%jmp/0xz T_9.16, 8;
%load/vec4 v0x55c406bd3b80_0;
%addi 1, 0, 32;
%assign/vec4 v0x55c406bd3b80_0, 0;
%load/vec4 v0x55c406bd3f50_0;
%pad/u 32;
%load/vec4 v0x55c406bd40c0_0;
%pad/u 4;
%ix/vec4 3;
%ix/load 4, 0, 0; Constant delay
%assign/vec4/a/d v0x55c406bd3ae0, 0, 4;
%pushi/vec4 1, 0, 1;
%assign/vec4 v0x55c406bd3a20_0, 0;
%load/vec4 v0x55c406bd40c0_0;
%pad/u 32;
%cmpi/e 3, 0, 32;
%jmp/0xz T_9.18, 4;
%vpi_call/w 2 128 "$finish" {0 0 0};
T_9.18 ;
%jmp T_9.17;
T_9.16 ;
%pushi/vec4 0, 0, 1;
%assign/vec4 v0x55c406bd3a20_0, 0;
T_9.17 ;
%load/vec4 v0x55c406bd3e80_0;
%assign/vec4 v0x55c406bd4870_0, 0;
%load/vec4 v0x55c406bd3c40_0;
%assign/vec4 v0x55c406bd47d0_0, 0;
%jmp T_9;
.thread T_9;
.scope S_0x55c406b87500;
T_10 ;
%delay 50000, 0;
%vpi_call/w 2 139 "$finish" {0 0 0};
%end;
.thread T_10;
# The file index is used to find the file name in the following table.
:file_names 4;
"N/A";
"<interactive>";
"adc_driver_tb.v";
"../library/adc_driver.v";

143
rtl/tb/adc_driver_tb.v Normal file
View File

@ -0,0 +1,143 @@
`timescale 10ns/10ns
module top();
reg clk = 0;
reg rstn = 1;
reg adc_so = 1;
wire adc_si;
wire adc_sck;
wire adc_ss;
reg sck_old = 1;
reg ss_old = 1;
wire [1:0] channel;
wire [11:0] adc_val;
wire vld;
reg ack = 0;
adc_driver dut(
.clk(clk),
.rstn(rstn),
.adc_so(adc_so),
.adc_si(adc_si),
.adc_ss(adc_ss),
.adc_sck(adc_sck),
.channel(channel),
.adc_val(adc_val),
.vld(vld),
.ack(ack)
);
reg configured;
reg [15:0] out;
initial begin
clk = 0;
rstn = 1;
adc_so = 1;
sck_old = 1;
configured = 0;
out = 0;
$dumpfile("adc_driver_tb.vcd");
$dumpvars;
end
always
#2 clk = !clk;
reg enabled;
integer bit_pos;
integer channel_num;
integer tosend;
integer configdata;
integer adc_pos;
integer adc_out[3:0];
integer i;
initial begin
bit_pos = 0;
channel_num = 0;
tosend = 0;
enabled = 0;
configdata = 0;
adc_pos = 0;
adc_so = 1;
for (i = 0; i < 4; i++)
adc_out[i] = 0;
end
always @* begin
case (adc_pos[1:0])
2'b00: out = 16'h01ff;
2'b01: out = 16'h1fff;
2'b10: out = 16'h2dea;
2'b11: out = 16'h3caf;
endcase
end
always @(posedge clk) begin
if (~adc_ss & ss_old) begin
enabled <= 1;
bit_pos <= 0;
end
if (enabled) begin
if (!configured) begin
// load into configdata if it hasn't
// been configured yet
if (~sck_old & adc_sck) begin
configdata <= (configdata << 1) | adc_si;
if (bit_pos >= 15) begin
configured <= 1;
bit_pos <= 0;
end else
bit_pos <= bit_pos + 1;
end
end else begin
if (~sck_old & adc_sck) begin
// TODO make sure the input is zero
end
if (sck_old & ~adc_sck) begin
// otherwise start loading in adc data
if (bit_pos >= 15) begin
bit_pos <= 0;
end else
bit_pos <= bit_pos + 1;
adc_so <= out[15-bit_pos];
end
end
end
if (vld & configured & ~ack) begin
adc_pos <= adc_pos + 1;
adc_out[channel] <= adc_val;
ack <= 1;
if (channel == 3) begin
// TODO check configdata
// TODO check adc values
$finish;
end
end else
ack <= 0;
ss_old <= adc_ss;
sck_old <= adc_sck;
end
initial begin
#50000
$finish;
end
endmodule

8506
rtl/tb/adc_driver_tb.vcd Normal file

File diff suppressed because it is too large Load Diff

37
rtl/tb/adc_test.cpp Normal file
View File

@ -0,0 +1,37 @@
#include "Vadc_driver.h"
#include "verilated.h"
#include <memory>
int main(int argc, char** argv, char** env) {
Verilated::commandArgs(argc, argv);
auto driver = std::unique_ptr<Vadc_driver>();
uint64_t tick = 0;
bool done = false;
driver->clk = 0;
driver->rstn = 1;
driver->adc_so = 0;
driver->ack = 0;
int sck_old = driver->sck;
while (!done) {
if (tick > 5) {
driver->rstn = 0;
}
if ((tick % 10) == 0) {
driver->clk = 1;
}
if ((tick % 10) == 5) {
driver->clk = 0;
}
driver->eval();
if (driver->sck & !sck_old) {
}
sck_old = driver->sck;
if (driver->vld) {
}
}
return 0;
}