From 8148f5567c7e2a4d601fbdcb020133f578ef93ca Mon Sep 17 00:00:00 2001 From: Maximilian Rehkopf Date: Mon, 9 Jul 2012 01:48:43 +0200 Subject: [PATCH] FPGA: properly synchronize external signals --- verilog/sd2snes/bsx.v | 10 ++++----- verilog/sd2snes/main.v | 44 +++++++++++++++++++++----------------- verilog/sd2snes/mcu_cmd.v | 2 +- verilog/sd2snes/msu.v | 13 ++++++----- verilog/sd2snes/srtc.v | 13 +++++------ verilog/sd2snes/upd77c25.v | 6 +++--- verilog/sd2snes_cx4/main.v | 44 +++++++++++++++++++++----------------- verilog/sd2snes_cx4/msu.v | 13 ++++++----- verilog/sd2sneslite/main.v | 40 ++++++++++++++++++++-------------- verilog/sd2sneslite/spi.v | 12 +++++++++-- 10 files changed, 114 insertions(+), 83 deletions(-) diff --git a/verilog/sd2snes/bsx.v b/verilog/sd2snes/bsx.v index 3b9e6b6..d77d097 100644 --- a/verilog/sd2snes/bsx.v +++ b/verilog/sd2snes/bsx.v @@ -102,12 +102,12 @@ assign bs_page_offset = bs_sta0_en ? 9'h032 reg [3:0] reg_oe_sreg; always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[2:0], reg_oe}; -wire reg_oe_falling = (reg_oe_sreg[3:0] == 4'b1000); -wire reg_oe_rising = (reg_oe_sreg[3:0] == 4'b0001); +wire reg_oe_falling = (reg_oe_sreg[3:1] == 3'b100); +wire reg_oe_rising = (reg_oe_sreg[3:1] == 3'b001); -reg [1:0] reg_we_sreg; -always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[0], reg_we}; -wire reg_we_rising = (reg_we_sreg[1:0] == 2'b01); +reg [2:0] reg_we_sreg; +always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[1:0], reg_we}; +wire reg_we_rising = (reg_we_sreg[2:1] == 2'b01); reg [1:0] pgm_we_sreg; always @(posedge clkin) pgm_we_sreg <= {pgm_we_sreg[0], pgm_we}; diff --git a/verilog/sd2snes/main.v b/verilog/sd2snes/main.v index 7e7a5fc..e3075b7 100644 --- a/verilog/sd2snes/main.v +++ b/verilog/sd2snes/main.v @@ -362,33 +362,37 @@ my_dcm snes_dcm( .STATUS(DCM_STATUS) ); -my_dcm snes_dcm2( - .CLKIN(SNES_SYSCLK), - .CLKFX(SYSCLK2), - .RST(DCM_RST) -); - assign DCM_RST=0; -reg [5:0] SNES_PARDr; -reg [5:0] SNES_READr; -reg [5:0] SNES_WRITEr; -reg [5:0] SNES_CPU_CLKr; +reg [7:0] SNES_PARDr; +reg [7:0] SNES_PAWRr; +reg [7:0] SNES_READr; +reg [7:0] SNES_WRITEr; +reg [7:0] SNES_CPU_CLKr; -wire SNES_PARD_start = (SNES_PARDr == 6'b111110); -wire SNES_RD_start = (SNES_READr == 6'b111110); -wire SNES_WR_start = (SNES_WRITEr == 6'b111110); -wire SNES_cycle_start = (SNES_CPU_CLKr[5:0] == 6'b000001); -wire SNES_cycle_end = (SNES_CPU_CLKr[5:0] == 6'b111110); +wire SNES_FAKE_CLK = &SNES_CPU_CLKr[2:1]; +//wire SNES_FAKE_CLK = ~(SNES_READ & SNES_WRITE); -always @(posedge SYSCLK2) begin - SNES_PARDr <= {SNES_PARDr[4:0], SNES_PARD}; +reg SNES_DEADr; +initial SNES_DEADr = 0; + +wire SNES_PARD_start = (SNES_PARDr[7:1] == 7'b1111110); +wire SNES_PAWR_start = (SNES_PAWRr[7:1] == 7'b0000001); +wire SNES_RD_start = (SNES_READr[7:1] == 7'b1111110); +wire SNES_WR_start = (SNES_WRITEr[7:1] == 7'b1111110); +wire SNES_WR_end = (SNES_WRITEr[7:1] == 7'b0000001); +wire SNES_cycle_start = ((SNES_CPU_CLKr[7:2] & SNES_CPU_CLKr[6:1]) == 6'b000001); +wire SNES_cycle_end = ((SNES_CPU_CLKr[7:2] & SNES_CPU_CLKr[6:1]) == 6'b111110); + +always @(posedge CLK2) begin + SNES_PARDr <= {SNES_PARDr[6:0], SNES_PARD}; end always @(posedge CLK2) begin - SNES_READr <= {SNES_READr[4:0], SNES_READ}; - SNES_WRITEr <= {SNES_WRITEr[4:0], SNES_WRITE}; - SNES_CPU_CLKr <= {SNES_CPU_CLKr[4:0], SNES_CPU_CLK}; + SNES_PAWRr <= {SNES_PAWRr[6:0], SNES_PAWR}; + SNES_READr <= {SNES_READr[6:0], SNES_READ}; + SNES_WRITEr <= {SNES_WRITEr[6:0], SNES_WRITE}; + SNES_CPU_CLKr <= {SNES_CPU_CLKr[6:0], SNES_CPU_CLK}; end address snes_addr( diff --git a/verilog/sd2snes/mcu_cmd.v b/verilog/sd2snes/mcu_cmd.v index 6706087..43982b7 100644 --- a/verilog/sd2snes/mcu_cmd.v +++ b/verilog/sd2snes/mcu_cmd.v @@ -462,7 +462,7 @@ end // nextaddr pulse generation always @(posedge clk) begin - mcu_nextaddr_buf <= {mcu_nextaddr_buf[0], mcu_rq_rdy}; + mcu_nextaddr_buf <= {mcu_nextaddr_buf[1:0], mcu_rq_rdy}; end parameter ST_RQ = 2'b01; diff --git a/verilog/sd2snes/msu.v b/verilog/sd2snes/msu.v index 213d285..f691a75 100644 --- a/verilog/sd2snes/msu.v +++ b/verilog/sd2snes/msu.v @@ -56,13 +56,15 @@ wire status_reset_en = (status_reset_we_r == 2'b01); reg [13:0] msu_address_r; wire [13:0] msu_address = msu_address_r; +initial msu_address_r = 13'b0; wire [7:0] msu_data; +reg [7:0] msu_data_r; -reg [1:0] msu_address_ext_write_sreg; +reg [2:0] msu_address_ext_write_sreg; always @(posedge clkin) - msu_address_ext_write_sreg <= {msu_address_ext_write_sreg[0], msu_address_ext_write}; -wire msu_address_ext_write_rising = (msu_address_ext_write_sreg[1:0] == 2'b01); + msu_address_ext_write_sreg <= {msu_address_ext_write_sreg[1:0], msu_address_ext_write}; +wire msu_address_ext_write_rising = (msu_address_ext_write_sreg[2:1] == 2'b01); reg [4:0] reg_enable_sreg; initial reg_enable_sreg = 5'b11111; @@ -70,11 +72,12 @@ always @(posedge clkin) reg_enable_sreg <= {reg_enable_sreg[3:0], enable}; reg [5:0] reg_oe_sreg; always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[4:0], reg_oe}; -wire reg_oe_rising = reg_enable_sreg[4] && (reg_oe_sreg[5:0] == 6'b000001); +wire reg_oe_rising = reg_enable_sreg[4] && (reg_oe_sreg[5:1] == 5'b00001); +wire reg_oe_falling = reg_enable_sreg[1] && (reg_oe_sreg[5:1] == 5'b11110); reg [5:0] reg_we_sreg; always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[4:0], reg_we}; -wire reg_we_rising = reg_enable_sreg[4] && (reg_we_sreg[5:0] == 6'b000001); +wire reg_we_rising = reg_enable_sreg[4] && (reg_we_sreg[5:1] == 5'b00001); reg [31:0] addr_out_r; assign addr_out = addr_out_r; diff --git a/verilog/sd2snes/srtc.v b/verilog/sd2snes/srtc.v index dd6e89d..fa95afc 100644 --- a/verilog/sd2snes/srtc.v +++ b/verilog/sd2snes/srtc.v @@ -44,13 +44,14 @@ reg rtc_we_r; assign rtc_we = rtc_we_r; assign data_out = data_out_r; -reg [3:0] reg_oe_sreg; -always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[2:0], reg_oe}; -wire reg_oe_falling = (reg_oe_sreg == 4'b1000); +reg [5:0] reg_oe_sreg; +always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[4:0], reg_oe}; +wire reg_oe_falling = (reg_oe_sreg[5:1] == 5'b11110); +wire reg_oe_rising = (reg_oe_sreg[5:1] == 5'b00001); -reg [1:0] reg_we_sreg; -always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[0], reg_we}; -wire reg_we_rising = (reg_we_sreg[1:0] == 2'b01); +reg [5:0] reg_we_sreg; +always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[4:0], reg_we}; +wire reg_we_rising = (reg_we_sreg[5:1] == 5'b00001); reg [1:0] reset_sreg; always @(posedge clkin) reset_sreg <= {reset_sreg[0], reset}; diff --git a/verilog/sd2snes/upd77c25.v b/verilog/sd2snes/upd77c25.v index 567483a..785fad3 100644 --- a/verilog/sd2snes/upd77c25.v +++ b/verilog/sd2snes/upd77c25.v @@ -128,8 +128,8 @@ always @(posedge CLK) reg_nCS_sreg <= {reg_nCS_sreg[3:0], nCS}; reg [5:0] reg_oe_sreg; initial reg_oe_sreg = 6'b111111; always @(posedge CLK) reg_oe_sreg <= {reg_oe_sreg[4:0], nRD}; -wire reg_oe_rising = !reg_nCS_sreg[4] && (reg_oe_sreg[5:0] == 6'b000001); -wire reg_oe_falling = (reg_oe_sreg[5:0] == 6'b100000); +wire reg_oe_rising = !reg_nCS_sreg[4] && (reg_oe_sreg[5:1] == 5'b00001); +wire reg_oe_falling = (reg_oe_sreg[5:1] == 5'b10000); reg [4:0] reg_DP_nCS_sreg; initial reg_DP_nCS_sreg = 5'b11111; @@ -138,7 +138,7 @@ always @(posedge CLK) reg_DP_nCS_sreg <= {reg_DP_nCS_sreg[3:0], DP_nCS}; reg [5:0] reg_we_sreg; initial reg_we_sreg = 6'b111111; always @(posedge CLK) reg_we_sreg <= {reg_we_sreg[4:0], nWR}; -wire reg_we_rising = !reg_nCS_sreg[4] && (reg_we_sreg[5:0] == 6'b000001); +wire reg_we_rising = !reg_nCS_sreg[4] && (reg_we_sreg[5:1] == 5'b00001); wire [15:0] ram_douta; wire [9:0] ram_addra; diff --git a/verilog/sd2snes_cx4/main.v b/verilog/sd2snes_cx4/main.v index 283293c..16c711e 100644 --- a/verilog/sd2snes_cx4/main.v +++ b/verilog/sd2snes_cx4/main.v @@ -266,33 +266,37 @@ my_dcm snes_dcm( .STATUS(DCM_STATUS) ); -my_dcm snes_dcm2( - .CLKIN(SNES_SYSCLK), - .CLKFX(SYSCLK2), - .RST(DCM_RST) -); - assign DCM_RST=0; -reg [5:0] SNES_PARDr; -reg [5:0] SNES_READr; -reg [5:0] SNES_WRITEr; -reg [5:0] SNES_CPU_CLKr; +reg [7:0] SNES_PARDr; +reg [7:0] SNES_PAWRr; +reg [7:0] SNES_READr; +reg [7:0] SNES_WRITEr; +reg [7:0] SNES_CPU_CLKr; -wire SNES_PARD_start = (SNES_PARDr == 6'b111110); -wire SNES_RD_start = (SNES_READr == 6'b111110); -wire SNES_WR_start = (SNES_WRITEr == 6'b111110); -wire SNES_cycle_start = (SNES_CPU_CLKr[5:0] == 6'b000001); -wire SNES_cycle_end = (SNES_CPU_CLKr[5:0] == 6'b111110); +wire SNES_FAKE_CLK = &SNES_CPU_CLKr[2:1]; +//wire SNES_FAKE_CLK = ~(SNES_READ & SNES_WRITE); -always @(posedge SYSCLK2) begin - SNES_PARDr <= {SNES_PARDr[4:0], SNES_PARD}; +reg SNES_DEADr; +initial SNES_DEADr = 0; + +wire SNES_PARD_start = (SNES_PARDr[7:1] == 7'b1111110); +wire SNES_PAWR_start = (SNES_PAWRr[7:1] == 7'b0000001); +wire SNES_RD_start = (SNES_READr[7:1] == 7'b1111110); +wire SNES_WR_start = (SNES_WRITEr[7:1] == 7'b1111110); +wire SNES_WR_end = (SNES_WRITEr[7:1] == 7'b0000001); +wire SNES_cycle_start = ((SNES_CPU_CLKr[7:2] & SNES_CPU_CLKr[6:1]) == 6'b000001); +wire SNES_cycle_end = ((SNES_CPU_CLKr[7:2] & SNES_CPU_CLKr[6:1]) == 6'b111110); + +always @(posedge CLK2) begin + SNES_PARDr <= {SNES_PARDr[6:0], SNES_PARD}; end always @(posedge CLK2) begin - SNES_READr <= {SNES_READr[4:0], SNES_READ}; - SNES_WRITEr <= {SNES_WRITEr[4:0], SNES_WRITE}; - SNES_CPU_CLKr <= {SNES_CPU_CLKr[4:0], SNES_CPU_CLK}; + SNES_PAWRr <= {SNES_PAWRr[6:0], SNES_PAWR}; + SNES_READr <= {SNES_READr[6:0], SNES_READ}; + SNES_WRITEr <= {SNES_WRITEr[6:0], SNES_WRITE}; + SNES_CPU_CLKr <= {SNES_CPU_CLKr[6:0], SNES_CPU_CLK}; end address snes_addr( diff --git a/verilog/sd2snes_cx4/msu.v b/verilog/sd2snes_cx4/msu.v index 2cf3711..e03e528 100644 --- a/verilog/sd2snes_cx4/msu.v +++ b/verilog/sd2snes_cx4/msu.v @@ -56,13 +56,15 @@ wire status_reset_en = (status_reset_we_r == 2'b01); reg [13:0] msu_address_r; wire [13:0] msu_address = msu_address_r; +initial msu_address_r = 13'b0; wire [7:0] msu_data; +reg [7:0] msu_data_r; -reg [1:0] msu_address_ext_write_sreg; +reg [2:0] msu_address_ext_write_sreg; always @(posedge clkin) - msu_address_ext_write_sreg <= {msu_address_ext_write_sreg[0], msu_address_ext_write}; -wire msu_address_ext_write_rising = (msu_address_ext_write_sreg[1:0] == 2'b01); + msu_address_ext_write_sreg <= {msu_address_ext_write_sreg[1:0], msu_address_ext_write}; +wire msu_address_ext_write_rising = (msu_address_ext_write_sreg[2:1] == 2'b01); reg [4:0] reg_enable_sreg; initial reg_enable_sreg = 5'b11111; @@ -70,11 +72,12 @@ always @(posedge clkin) reg_enable_sreg <= {reg_enable_sreg[3:0], enable}; reg [5:0] reg_oe_sreg; always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[4:0], reg_oe}; -wire reg_oe_rising = reg_enable_sreg[4] && (reg_oe_sreg[5:0] == 6'b000001); +wire reg_oe_rising = reg_enable_sreg[4] && (reg_oe_sreg[5:1] == 5'b00001); +wire reg_oe_falling = reg_enable_sreg[1] && (reg_oe_sreg[5:1] == 5'b11110); reg [5:0] reg_we_sreg; always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[4:0], reg_we}; -wire reg_we_rising = reg_enable_sreg[4] && (reg_we_sreg[5:0] == 6'b000001); +wire reg_we_rising = reg_enable_sreg[4] && (reg_we_sreg[5:1] == 5'b00001); reg [31:0] addr_out_r; assign addr_out = addr_out_r; diff --git a/verilog/sd2sneslite/main.v b/verilog/sd2sneslite/main.v index 5b08d75..4c9f1ad 100644 --- a/verilog/sd2sneslite/main.v +++ b/verilog/sd2sneslite/main.v @@ -152,28 +152,36 @@ my_dcm snes_dcm( assign DCM_RST=0; -reg [5:0] SNES_READr; -reg [5:0] SNES_WRITEr; -reg [12:0] SNES_CPU_CLKr; -reg [5:0] SNES_RWr; -reg [23:0] SNES_ADDRr; +reg [7:0] SNES_PARDr; +reg [7:0] SNES_PAWRr; +reg [7:0] SNES_READr; +reg [7:0] SNES_WRITEr; +reg [7:0] SNES_CPU_CLKr; -wire SNES_RW = (SNES_READ & SNES_WRITE); +wire SNES_FAKE_CLK = &SNES_CPU_CLKr[2:1]; +//wire SNES_FAKE_CLK = ~(SNES_READ & SNES_WRITE); -wire SNES_RW_start = (SNES_RWr == 6'b111110); // falling edge marks beginning of cycle -wire SNES_RD_start = (SNES_READr == 6'b111110); -wire SNES_WR_start = (SNES_WRITEr == 6'b111110); -wire SNES_cycle_start = (SNES_CPU_CLKr[5:0] == 6'b000001); -wire SNES_cycle_end = (SNES_CPU_CLKr[5:0] == 6'b111110); +reg SNES_DEADr; +initial SNES_DEADr = 0; + +wire SNES_PARD_start = (SNES_PARDr[7:1] == 7'b1111110); +wire SNES_PAWR_start = (SNES_PAWRr[7:1] == 7'b0000001); +wire SNES_RD_start = (SNES_READr[7:1] == 7'b1111110); +wire SNES_WR_start = (SNES_WRITEr[7:1] == 7'b1111110); +wire SNES_WR_end = (SNES_WRITEr[7:1] == 7'b0000001); +wire SNES_cycle_start = ((SNES_CPU_CLKr[7:2] & SNES_CPU_CLKr[6:1]) == 6'b000001); +wire SNES_cycle_end = ((SNES_CPU_CLKr[7:2] & SNES_CPU_CLKr[6:1]) == 6'b111110); always @(posedge CLK2) begin - SNES_READr <= {SNES_READr[4:0], SNES_READ}; - SNES_WRITEr <= {SNES_WRITEr[4:0], SNES_WRITE}; - SNES_CPU_CLKr <= {SNES_CPU_CLKr[11:0], SNES_CPU_CLK}; - SNES_RWr <= {SNES_RWr[4:0], SNES_RW}; + SNES_PARDr <= {SNES_PARDr[6:0], SNES_PARD}; end -wire ROM_SEL; +always @(posedge CLK2) begin + SNES_PAWRr <= {SNES_PAWRr[6:0], SNES_PAWR}; + SNES_READr <= {SNES_READr[6:0], SNES_READ}; + SNES_WRITEr <= {SNES_WRITEr[6:0], SNES_WRITE}; + SNES_CPU_CLKr <= {SNES_CPU_CLKr[6:0], SNES_CPU_CLK}; +end address snes_addr( .CLK(CLK2), diff --git a/verilog/sd2sneslite/spi.v b/verilog/sd2sneslite/spi.v index f19abad..02d15a5 100644 --- a/verilog/sd2sneslite/spi.v +++ b/verilog/sd2sneslite/spi.v @@ -37,9 +37,17 @@ module spi( reg [7:0] cmd_data_r; reg [7:0] param_data_r; -reg [1:0] SSELr; always @(posedge clk) SSELr <= {SSELr[0], SSEL}; +reg [2:0] SSELr; +reg [2:0] SSELSCKr; + +always @(posedge clk) SSELr <= {SSELr[1:0], SSEL}; +always @(posedge SCK) SSELSCKr <= {SSELSCKr[1:0], SSEL}; + +wire SSEL_inactive = SSELr[1]; wire SSEL_active = ~SSELr[1]; // SSEL is active low -wire SSEL_startmessage = (SSELr[1:0]==2'b10); // message starts at falling edge +wire SSEL_startmessage = (SSELr[2:1]==2'b10); // message starts at falling edge +wire SSEL_endmessage = (SSELr[2:1]==2'b01); // message stops at rising edge +assign endmessage = SSEL_endmessage; assign startmessage = SSEL_startmessage; // bit count for one SPI byte + byte count for the message