From faaf9415a03eb91bf5b68b5d22a6ebc0d7e46db4 Mon Sep 17 00:00:00 2001 From: Kelvin Ly Date: Tue, 7 Jan 2020 23:57:08 -0500 Subject: [PATCH] Start work on testing ADC driver --- rtl/.gitignore | 1 + rtl/Makefile | 2 +- rtl/bldc.pcf | 5 ++ rtl/bldc.v | 135 ++++++++++++++++++++++++++++++++--- rtl/library/adc_driver.v | 17 +++-- rtl/library/bram512x8.v | 18 +++++ rtl/library/uart_tx_115200.v | 26 +++---- 7 files changed, 173 insertions(+), 31 deletions(-) create mode 100644 rtl/library/bram512x8.v diff --git a/rtl/.gitignore b/rtl/.gitignore index a18e158..1972059 100644 --- a/rtl/.gitignore +++ b/rtl/.gitignore @@ -2,3 +2,4 @@ *.bin *.json *.rpt +*.log diff --git a/rtl/Makefile b/rtl/Makefile index 3067f01..9234207 100644 --- a/rtl/Makefile +++ b/rtl/Makefile @@ -10,7 +10,7 @@ ${FN}_filled.bin: ${FN}.bin dd if=$< of=$@ conv=notrunc ${FN}.json: ${FN}.v $(shell find library -type f -name '*.v') - ./run_yosys.sh ${FN} + ./run_yosys.sh ${FN} | tee bldc.log ${FN}.asc: ${FN}.json ${FN}.pcf nextpnr-ice40 ${NEXTPNR_OPTS} --pcf "${FN}.pcf" --json "${FN}.json" --asc "${FN}.asc" diff --git a/rtl/bldc.pcf b/rtl/bldc.pcf index 4a67d08..41213cb 100644 --- a/rtl/bldc.pcf +++ b/rtl/bldc.pcf @@ -1,4 +1,9 @@ set_io if_int 32 set_io dbg_tx 48 +set_io adc_sck 28 +set_io adc_ss 27 +set_io adc_si 26 +set_io adc_so 25 + set_io clk 20 diff --git a/rtl/bldc.v b/rtl/bldc.v index 3dddb22..9867da2 100644 --- a/rtl/bldc.v +++ b/rtl/bldc.v @@ -1,32 +1,145 @@ module bldc ( input clk, output dbg_tx, - output if_int + output if_int, + + output adc_ss, + output adc_sck, + input adc_so, + output adc_si ); -reg [7:0] dbg_buf = 8'hac; -reg dbg_buf_vld = 1; -wire dbg_tx_ack; +reg [7:0] dbg_buf = 0; +reg dbg_buf_vld = 0; +wire dbg_tx_rdy; + +reg [15:0] adc_vals[3:0]; +reg [1:0] vals_idx = 0; +initial begin + adc_vals[0] = 0; + adc_vals[1] = 0; + adc_vals[2] = 0; + adc_vals[3] = 0; +end + +wire [1:0] adc_channel; +wire [11:0] adc_val; +wire adc_vld; +reg adc_ack = 0; + +adc_driver adc0( + .clk(clk), + .rstn(1'b1), + .so(adc_so), + .si(adc_si), + .ss(adc_ss), + .sck(adc_sck), + + .channel(adc_channel), + .val(adc_val), + .vld(adc_vld), + .ack(adc_ack) + ); uart_tx_115200 dbg( .clk_25mhz(clk), .rstn(1'b1), .tx(dbg_tx), .tx_buf(dbg_buf), - .tx_vld(dbg_buf_vld), - .tx_ack(dbg_tx_ack) + .vld(dbg_buf_vld), + .rdy(dbg_tx_rdy) ); -reg [3:0] tmp = 0; +reg [7:0] tmp3 = 0; +reg [7:0] tmp2 = 0; +reg [7:0] tmp = 0; assign if_int = tmp[3]; +reg uart_end = 0; +reg uart_bsy = 0; + +// stores {cur_channel_idx, cur_nibble} +reg [3:0] cur_idx = 0; + +reg [15:0] cur_channel; +reg [3:0] cur_nibble; +reg [7:0] nibble_hex; + +always @(posedge clk) begin + cur_channel <= adc_vals[cur_idx[3:2]]; + + case (cur_idx[1:0]) + 2'b00: cur_nibble <= cur_channel[3:0]; + 2'b01: cur_nibble <= cur_channel[7:4]; + 2'b10: cur_nibble <= cur_channel[11:8]; + 2'b11: cur_nibble <= cur_channel[15:12]; + endcase + + case (cur_nibble) + 4'h0: nibble_hex <= 48; + 4'h1: nibble_hex <= 49; + 4'h2: nibble_hex <= 50; + 4'h3: nibble_hex <= 51; + 4'h4: nibble_hex <= 52; + 4'h5: nibble_hex <= 53; + 4'h6: nibble_hex <= 54; + 4'h7: nibble_hex <= 55; + 4'h8: nibble_hex <= 56; + 4'h9: nibble_hex <= 57; + 4'ha: nibble_hex <= 97; + 4'hb: nibble_hex <= 98; + 4'hc: nibble_hex <= 99; + 4'hd: nibble_hex <= 100; + 4'he: nibble_hex <= 101; + 4'hf: nibble_hex <= 102; + endcase +end + always @(posedge clk) begin tmp <= tmp + 1; - if (dbg_tx_ack) begin - dbg_buf <= dbg_buf + 1; - dbg_buf_vld = 1; + if (&tmp) begin + tmp2 <= tmp2 + 1; + if (&tmp2) + tmp3 <= tmp3 + 1; + end + + // 25 MHz / 2^(8+8+7) = 3 Hz + if (&tmp & &tmp2 & &tmp3[6:0]) begin + uart_bsy <= 1; + cur_idx <= 0; + end + + if (dbg_tx_rdy) begin + if (uart_bsy) begin + if (~uart_end) begin + // write the ADC data to the UART + dbg_buf <= nibble_hex; + dbg_buf_vld <= 1; + + cur_idx <= cur_idx + 1; + if (&cur_idx) + uart_end <= 1; + end else begin + // write newline + dbg_buf <= 8'h0a; + dbg_buf_vld <= 1; + + uart_end <= 0; + uart_bsy <= 0; + end + end end else begin - dbg_buf_vld = 0; + dbg_buf_vld <= 0; + end + + if (adc_vld) begin + adc_ack <= 1; + vals_idx <= vals_idx + 1; + if (~uart_bsy) begin + adc_vals[vals_idx] <= {adc_channel, adc_val}; + end + end else begin + adc_ack <= 0; end end diff --git a/rtl/library/adc_driver.v b/rtl/library/adc_driver.v index 6baed45..685dbda 100644 --- a/rtl/library/adc_driver.v +++ b/rtl/library/adc_driver.v @@ -1,3 +1,7 @@ +// driver for the MAX1141 ADC used in the board +// it has 4 analog inputs, and is configured to automatically +// scan them sequentially while being driven by SCK +// it uses module adc_driver( input clk, input rstn, @@ -15,15 +19,15 @@ module adc_driver( reg [1:0] channel_ff = 0; reg [11:0] adc_val_ff = 0; -reg vld_ff = 0; +reg new = 0; assign channel = channel_ff; assign val = adc_val_ff; -assign vld = vld_ff; +assign vld = new & ~ack; -reg [2:0] sck_strobe = 0; +reg [1:0] sck_strobe = 0; wire strobe = &sck_strobe; -wire strobe2 = &(sck_strobe^3'b100); +wire strobe2 = &(sck_strobe^2'b10); always @(posedge clk) begin if (rstn) @@ -76,6 +80,7 @@ always @* begin sck_next = 1; ss_next = 1; + si_next = 0; if (rstn) begin // latch sck and ss state until the strobe happens @@ -158,11 +163,11 @@ always @(posedge clk) begin // write the data out when write_out is asserted if (write_out) begin {channel_ff, adc_val_ff} <= so_ff_next[13:0]; - vld_ff <= 1; + new <= 1; end // deassert vld when the data is acknowledged if (ack) - vld_ff <= 0; + new <= 0; end endmodule diff --git a/rtl/library/bram512x8.v b/rtl/library/bram512x8.v new file mode 100644 index 0000000..6db3c94 --- /dev/null +++ b/rtl/library/bram512x8.v @@ -0,0 +1,18 @@ +module bram512x8( + input clk, + input [8:0] raddr, + output [7:0] reg rdat, + input [8:0] waddr, + input [7:0] wdat, + input wen + ); + + + reg [7:0] mem[511:0]; + always @(posedge clk) begin + if (wen) + mem[waddr] <= wdat; + rdat <= mem[rdat]; + end + +endmodule diff --git a/rtl/library/uart_tx_115200.v b/rtl/library/uart_tx_115200.v index 6310b58..2cc5e40 100644 --- a/rtl/library/uart_tx_115200.v +++ b/rtl/library/uart_tx_115200.v @@ -3,12 +3,12 @@ module uart_tx_115200( input rstn, output reg tx, input [7:0] tx_buf, - input tx_vld, - output tx_ack, + input vld, + output rdy, ); -reg [2:0] bit = 0; -reg [2:0] bit_next; +reg [2:0] b = 0; +reg [2:0] b_next; reg [7:0] counter = 0; reg [7:0] counter_next; @@ -18,13 +18,13 @@ localparam IDLE = 0, START = 1, TX = 2, STOP = 3; reg [1:0] state = IDLE; reg [1:0] state_next; -assign tx_ack = (state == IDLE); +assign rdy = (state == IDLE); always @* begin case (state) IDLE: tx = 1; START: tx = 0; - TX: tx = tx_buf[bit]; + TX: tx = tx_buf[b]; STOP: tx = 1; endcase end @@ -32,19 +32,19 @@ end always @* begin state_next = state; counter_next = counter; - bit_next = bit; + b_next = b; if (rstn) begin if (counter == 216) begin counter_next = 0; - bit_next = bit + 1; + b_next = b + 1; end else begin counter_next = counter + 1; end case (state) IDLE: begin - if (tx_vld) begin + if (vld) begin state_next = START; counter_next = 0; end @@ -52,11 +52,11 @@ always @* begin START: begin if (counter == 216) begin state_next = TX; - bit_next = 0; + b_next = 0; end end TX: begin - if ((counter == 216) && (bit == 7)) begin + if ((counter == 216) && (b == 7)) begin state_next = STOP; end end @@ -69,14 +69,14 @@ always @* begin end else begin state_next = IDLE; counter_next = 0; - bit_next = 0; + b_next = 0; end end always @(posedge clk_25mhz) begin state <= state_next; counter <= counter_next; - bit <= bit_next; + b <= b_next; end endmodule