From 48d87584bc7004afbe600fa0d77d17b12e46b27b Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 26 May 2019 12:13:04 +0200 Subject: [PATCH] add synchronizer for external levels. Now we're cooking! --- hdl/buspirate/buspirate.v | 103 +++++++++++++++++--------------- hdl/buspirate/buspirate_tb.gtkw | 29 ++++++--- hdl/buspirate/buspirate_tb.v | 87 ++++++++++++++++----------- hdl/buspirate/synchronizer.v | 18 ++++++ 4 files changed, 145 insertions(+), 92 deletions(-) create mode 100644 hdl/buspirate/synchronizer.v diff --git a/hdl/buspirate/buspirate.v b/hdl/buspirate/buspirate.v index 29065b1..ea45480 100644 --- a/hdl/buspirate/buspirate.v +++ b/hdl/buspirate/buspirate.v @@ -7,6 +7,7 @@ `include "pwm.v" `include "spimaster.v" `include "fifo.v" +`include "synchronizer.v" module top (clock, reset, bufdir_mosi, bufod_mosi, bufio_mosi, bufdir_clock, bufod_clock, bufio_clock, @@ -29,7 +30,7 @@ module top (clock, reset, input wire [7:0] lat; input wire mc_oe, mc_ce, mc_we; input wire [MC_ADD_WIDTH-1:0] mc_add; - input wire [MC_DATA_WIDTH-1:0] mc_data; + inout wire [MC_DATA_WIDTH-1:0] mc_data; inout wire irq0, irq1; output wire sram_clock, sram0_cs, sram1_cs; inout wire [3:0] sram0_sio, sram1_sio; @@ -39,8 +40,14 @@ module top (clock, reset, wire buftdo_mosi,buftdo_clock,buftdo_miso,buftdo_cs,buftdo_aux; wire buftdi_mosi,buftdi_clock,buftdi_miso,buftdi_cs,buftdi_aux; // Memory controller interface + reg [MC_ADD_WIDTH-1:0] mc_add_reg; + //reg [MC_DATA_WIDTH-1:0] mc_din_reg; wire [MC_DATA_WIDTH-1:0] mc_din; - reg [MC_DATA_WIDTH-1:0] mc_dout; + //reg [MC_DATA_WIDTH-1:0] mc_dout_reg; + wire [MC_DATA_WIDTH-1:0] mc_dout; + + + // Interrupts reg irq0_out, irq1_out; wire irq0_in, irq0_dir, irq1_in, irq1_dir; @@ -48,7 +55,7 @@ module top (clock, reset, wire temp; // PWM - wire pwm_out; + wire pwm_out, pwm_reset; reg [15:0] pwm_on, pwm_off; // SPI master @@ -61,14 +68,7 @@ module top (clock, reset, // spi signals wire spi_miso,spi_mosi,spi_clock,spi_cs; - localparam N = 24; - reg [N:0] count; //count[N] - //rst, // reset - //clkin, // clock in - //clkout, // clock out - //onperiod, // #ticks period ontime - //offperiod // #ticks period offtime - pwm AUX_PWM(reset, clock,pwm_out, pwm_on,pwm_off); + pwm AUX_PWM(reset||pwm_reset, clock,pwm_out, pwm_on,pwm_off); spimaster SPI_MASTER( // general control @@ -93,22 +93,24 @@ module top (clock, reset, ); //FIFO - wire in_fifo_in_nempty, in_fifo_in_full, in_fifo_out_nempty; + wire in_fifo_in_nempty, in_fifo_in_full, in_fifo_out_nempty,in_fifo_in_shift,in_fifo_out_pop; wire out_fifo_in_nempty, out_fifo_in_full, out_fifo_out_nempty; - fifo #( - .WIDTH(16), - .DEPTH(4) - ) FIFO_IN ( + + //assign spi_go=(in_fifo_out_nempty && !spi_state)? 1'b1:1'b0; + assign in_fifo_in_shift=(mc_add==6'h00)?mc_we_sync:1'b0; + //assign in_fifo_out_pop=!spi_state; + + fifo FIFO_IN ( .clock(clock), - .in_shift(mc_we), - .in_data(mc_data), + .in_shift(in_fifo_in_shift), + .in_data(mc_din), .in_full(in_fifo_in_full), .in_nempty(in_fifo_in_nempty), - .out_pop(!spi_state), + .out_pop(in_fifo_out_pop), .out_data(spi_din), .out_nempty(in_fifo_out_nempty) - ), FIFO_OUT ( + );/*, FIFO_OUT ( .clock(clock), .in_shift(spi_go), //??? .in_data(spi_dout), // in data @@ -118,7 +120,7 @@ module top (clock, reset, .out_pop(mc_ce), //input out_pop, .out_data(mc_din), //out data, .out_nempty(out_fifo_out_nempty) //output reg out_nempty - ); + );*/ // oe od dir din dout bufdir bufod the pins from the SB_IO block below iobuf MOSI_BUF(1'b1, 1'b0, 1'b0, spi_mosi, temp, bufdir_mosi, bufod_mosi, buftoe_mosi, buftdo_mosi,buftdi_mosi); @@ -127,35 +129,42 @@ module top (clock, reset, iobuf CS_BUF(1'b1, 1'b0, 1'b0, spi_cs, temp, bufdir_cs, bufod_cs, buftoe_cs, buftdo_cs,buftdi_cs); iobuf AUX_BUF(1'b1, 1'b0, 1'b0, pwm_out, temp, bufdir_aux, bufod_aux, buftoe_aux, buftdo_aux,buftdi_aux); - assign spi_go=(in_fifo_out_nempty && !spi_state)? 1'b1:1'b0; - - always @(posedge clock) - count <= count + 1; + wire mc_we_sync; + sync MC_WE(clock, mc_we, mc_we_sync); - /*always @(posedge clock) + assign pwm_reset=(mc_add==6'h1a)?!mc_we:1'b0; + //writing to chip + always @(negedge mc_we) begin - if(in_fifo_out_nempty && !spi_state) begin - spi_go<=1'b1; - end else begin - spi_go<=1'b0; - end - end*/ - - always @ (posedge mc_we) + //mc_add_reg<=mc_add; + //mc_din_reg<=mc_data; case(mc_add) - 6'h00: - begin - - end - 6'h19: - begin - pwm_on=mc_data; - pwm_off=mc_data; - end + 6'h19: // pwm on-time register + begin + pwm_on <= mc_din; + end + 6'h1a: // pwm off-time register + begin + pwm_off <= mc_din; + end endcase + end - - + //reading from chip + /*always @(negedge mc_oe) + begin + case(mc_add) + 6'h19: // pwm on-time register + begin + mc_din <= pwm_on; + end + 6'h1a: // pwm off-time register + begin + mc_din <= pwm_off; + end + endcase + end +*/ //define the tristate data pin explicitly in the top module // Bus Pirate IO pins SB_IO #( @@ -204,7 +213,7 @@ module top (clock, reset, .D_IN_0(buftdi_aux) //data in wire ); // Memory controller data pins - /* SB_IO #( + SB_IO #( .PIN_TYPE(6'b1010_01), .PULLUP(1'b0) ) mc_io [MC_DATA_WIDTH-1:0] ( @@ -212,7 +221,7 @@ module top (clock, reset, .OUTPUT_ENABLE(!mc_oe), .D_OUT_0(mc_dout), .D_IN_0(mc_din) - );*/ + ); // Interrupt pins SB_IO #( .PIN_TYPE(6'b1010_01), diff --git a/hdl/buspirate/buspirate_tb.gtkw b/hdl/buspirate/buspirate_tb.gtkw index 76ddfcb..7ab617d 100644 --- a/hdl/buspirate/buspirate_tb.gtkw +++ b/hdl/buspirate/buspirate_tb.gtkw @@ -1,15 +1,15 @@ [*] [*] GTKWave Analyzer v3.3.77 (w)1999-2016 BSI -[*] Sat May 25 10:59:36 2019 +[*] Sun May 26 09:54:39 2019 [*] [dumpfile] "C:\Users\ian\Desktop\buspirateultra\hdl\buspirate\buspirate_tb.vcd" -[dumpfile_mtime] "Sat May 25 10:55:16 2019" -[dumpfile_size] 32086 +[dumpfile_mtime] "Sun May 26 09:54:16 2019" +[dumpfile_size] 38038 [savefile] "C:\Users\ian\Desktop\buspirateultra\hdl\buspirate\buspirate_tb.gtkw" [timestart] 0 [size] 1920 1017 [pos] -1 -1 -*-17.491154 350900 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +*-19.344418 328000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [treeopen] buspirate_tb. [treeopen] buspirate_tb.buspirate. [sst_width] 331 @@ -36,12 +36,23 @@ buspirate_tb.buspirate.SPI_MASTER.state buspirate_tb.buspirate.FIFO_IN.in_shift buspirate_tb.buspirate.FIFO_IN.out_nempty buspirate_tb.buspirate.FIFO_IN.out_pop +buspirate_tb.buspirate.spi_go +@29 +buspirate_tb.buspirate.clock +@28 +buspirate_tb.buspirate.FIFO_IN.in_pos[1:0] +buspirate_tb.buspirate.FIFO_IN.next_in_pos[1:0] +buspirate_tb.buspirate.FIFO_IN.in_nempty +buspirate_tb.buspirate.FIFO_IN.out_nempty +buspirate_tb.buspirate.FIFO_IN.in_full @22 -buspirate_tb.buspirate.FIFO_OUT.in_data[15:0] +buspirate_tb.buspirate.FIFO_IN.in_data[7:0] @28 -buspirate_tb.buspirate.FIFO_OUT.in_shift -buspirate_tb.buspirate.FIFO_OUT.in_pos[1:0] -@23 -buspirate_tb.buspirate.FIFO_OUT.in_data[15:0] +buspirate_tb.buspirate.MC_WE.clock +buspirate_tb.buspirate.MC_WE.i +buspirate_tb.buspirate.MC_WE.o +buspirate_tb.buspirate.MC_WE.r1 +buspirate_tb.buspirate.MC_WE.r2 +buspirate_tb.buspirate.MC_WE.r3 [pattern_trace] 1 [pattern_trace] 0 diff --git a/hdl/buspirate/buspirate_tb.v b/hdl/buspirate/buspirate_tb.v index 09e0e01..0df1949 100644 --- a/hdl/buspirate/buspirate_tb.v +++ b/hdl/buspirate/buspirate_tb.v @@ -25,11 +25,14 @@ module buspirate_tb(); wire [7:0] lat; reg mc_oe, mc_ce, mc_we; reg [MC_ADD_WIDTH-1:0] mc_add; - reg [MC_DATA_WIDTH-1:0] mc_data; + wire [MC_DATA_WIDTH-1:0] mc_data; + reg [MC_DATA_WIDTH-1:0] mc_data_reg; wire irq0, irq1; wire sram_clock, sram0_cs, sram1_cs; wire [3:0] sram0_sio, sram1_sio; + assign mc_data=mc_data_reg; + top buspirate( .clock(clk), .reset(rst), @@ -126,58 +129,70 @@ module buspirate_tb(); initial begin $dumpfile(`DUMPSTR(`VCD_OUTPUT)); $dumpvars(0, buspirate_tb); - /* oe=1'b0; //initial values - od=1'b0; - dir=1'b0; - din=1'b0; - iopin_input=1'bz;*/ miso_input=1'b1; - mc_we=0; + mc_we=1; + mc_oe=1; @(negedge rst); // wait for reset repeat(10) @(posedge clk); - mc_add = 6'h00; - mc_data = 16'h0055; - repeat(1) @(posedge clk); + + mc_add = 6'h19; + mc_data_reg <= 16'h0003; + repeat(6)@(posedge clk); + mc_we=0; + repeat(6)@(posedge clk); mc_we=1; - repeat(1) @(posedge clk); + repeat(6)@(posedge clk); + mc_add = 6'h1a; + mc_data_reg <= 16'h0003; + repeat(6)@(posedge clk); mc_we=0; - repeat(2) @(posedge clk); + repeat(6)@(posedge clk); + mc_we=1; + repeat(6)@(posedge clk); mc_add = 6'h00; - mc_data = 16'h00FF; - repeat(1) @(posedge clk); + mc_data_reg <= 16'h0055; + repeat(6)@(posedge clk); + mc_we=0; + repeat(6)@(posedge clk); mc_we=1; - repeat(1) @(posedge clk); + repeat(6)@(posedge clk); + mc_data_reg <= 16'h0001; + repeat(6)@(posedge clk); mc_we=0; - repeat(2) @(posedge clk); - - - mc_add = 6'h19; - mc_data = 16'b10; - repeat(1) @(posedge clk); + repeat(6)@(posedge clk); mc_we=1; - repeat(1) @(posedge clk); + repeat(6)@(posedge clk); + mc_data_reg <= 16'h0002; + repeat(6)@(posedge clk); mc_we=0; - repeat(2) @(posedge clk); + repeat(6)@(posedge clk); + mc_we=1; + repeat(6)@(posedge clk); - mc_add = 6'h19; - mc_data = 16'b01; - repeat(1) @(posedge clk); + + mc_data_reg <= 16'h0055; + repeat(6)@(posedge clk); + mc_we=0; + repeat(6)@(posedge clk); mc_we=1; - repeat(1) @(posedge clk); + repeat(6)@(posedge clk); + /* mc_data_reg <= 16'h0001; + @(posedge clk); mc_we=0; - repeat(20) @(posedge clk); - - mc_add = 6'h19; - mc_data = 16'b11; - miso_input=1'b0; - repeat(1) @(posedge clk); + @(posedge clk); mc_we=1; - repeat(1) @(posedge clk); + @(posedge clk); + mc_data_reg <= 16'h0002; + @(posedge clk); mc_we=0; - repeat(20) @(posedge clk); + @(posedge clk); + mc_we=1; + @(posedge clk); +*/ + - repeat(200) @(posedge clk); + repeat(100) @(posedge clk); $finish; end diff --git a/hdl/buspirate/synchronizer.v b/hdl/buspirate/synchronizer.v new file mode 100644 index 0000000..948946e --- /dev/null +++ b/hdl/buspirate/synchronizer.v @@ -0,0 +1,18 @@ +//https://electronics.stackexchange.com/questions/102646/how-to-efficiently-implement-a-single-output-pulse-from-a-long-input-on-altera +`ifndef __SYNCHRONIZER__ +`define __SYNCHRONIZER__ +module sync( +input wire clock, +input wire i, +output wire o +); + reg r1, r2, r3; + + always @(posedge clock) begin + r1 <= i; // first stage of 2-stage synchronizer + r2 <= r1; // second stage of 2-stage synchronizer + r3 <= r2; // edge detector memory + end + assign o = (r2 && !r3); +endmodule +`endif