]> jspc29.x-matter.uni-frankfurt.de Git - vhdlbasics.git/commitdiff
new 16 bit scheme for flash, IF
authorIngo Froehlich <ingo@nomail.fake>
Tue, 30 Jan 2018 14:39:17 +0000 (15:39 +0100)
committerIngo Froehlich <ingo@nomail.fake>
Tue, 30 Jan 2018 14:39:17 +0000 (15:39 +0100)
machxo3/flash/UFM_WB_16bit.v [new file with mode: 0644]
machxo3/flash/generic_flash_ctrl.vhd

diff --git a/machxo3/flash/UFM_WB_16bit.v b/machxo3/flash/UFM_WB_16bit.v
new file mode 100644 (file)
index 0000000..f528b65
--- /dev/null
@@ -0,0 +1,1184 @@
+// --------------------------------------------------------------------
+// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
+// --------------------------------------------------------------------
+// Copyright (c) 2001 - 2012 by Lattice Semiconductor Corporation  
+// --------------------------------------------------------------------  
+//  
+// Permission:                    
+//
+// Lattice Semiconductor grants permission to use this code for use
+// in synthesis for any Lattice programmable logic product. Other
+// use of this code, including the selling or duplication of any
+// portion is strictly prohibited.
+//
+// Disclaimer:
+//
+// This verilog source code is intended as a design reference
+// which illustrates how these types of functions can be implemented.
+// It is the user's responsibility to verify their design for
+// consistency and functionality through the use of formal
+// verification methods. Lattice Semiconductor provides no warranty
+// regarding the use or functionality of this code.
+//
+// --------------------------------------------------------------------
+//
+// Lattice Semiconductor Corporation
+// 5555 NE Moore Court
+// Hillsboro, OR 97214
+// U.S.A
+//
+// TEL: 1-800-Lattice (USA and Canada)
+// 503-268-8001 (other locations)
+//
+// web: http://www.latticesemi.com/
+// email: techsupport@latticesemi.com
+//  
+// --------------------------------------------------------------------
+// Code Revision History :
+// --------------------------------------------------------------------
+// Ver: | Author  |Mod. Date |Changes Made:
+// V1.0 | Vijay   |3/09/12    |Initial ver
+// V1.1 | SHossner|6/08/12    |Added READ_DELAY parameter
+//  
+// --------------------------------------------------------------------
+
+`timescale 1ns / 100ps
+`include "efb_define_def.v"
+//`include "/d/jspc29/lattice/diamond/2.0/ispfpga/verilog/data/machxo2/GSR.v"
+//`include "/d/jspc29/lattice/diamond/2.0/ispfpga/verilog/data/machxo2/PUR.v"
+
+module UFM_WB(
+              input clk_i
+              , input rst_n
+              , input[2:0] cmd
+              , input[15:0] ufm_page //changed to 16bit, IF
+             , input select_cfg  //added, IF
+              , input GO
+              , output reg BUSY
+              , output reg ERR
+   
+              /***************** DPRAM port B signals *************/
+              , output reg mem_clk
+              , output reg mem_we
+              , output reg mem_ce
+              , output reg[3:0] mem_addr
+              , output reg[7:0] mem_wr_data
+              , input [7:0] mem_rd_data
+
+              );
+
+   //*****************
+   // For clk_i speeds less than 16.6MHz, set READ_DELAY to zero for fastest UFM read operation
+   // For clk_i speeds greater than 16.6MHz, set READ_DELAY as follows: 
+   // Calculate minimum READ_DELAY as follows:
+   //  READ_DELAY(min) = 240/PERIOD - 4
+   //  Where PERIOD = clk_i period in ns
+   //  Example, for clk_i = 45MHz, PERIOD = 22.22ns and READ_DELAY = 7 (6.8 rounded up)
+   //
+   // Or choose from the following table:
+   //   READ_DELAY  |    Max Clk_i
+   //   ------------+-------------
+   //       0       |     16.6 Mhz
+   //       2       |     25.0 Mhz
+   //       4       |     33.3 Mhz
+   //       8       |     50.0 Mhz
+   //      12       |     66.6 Mhz
+   //      14       |     75.0 Mhz
+
+   parameter READ_DELAY = 4;
+   //*****************
+
+   wire             ufm_enable_cmd;
+   wire             ufm_read_cmd;
+   wire             ufm_write_cmd;
+   wire             ufm_erase_cmd;
+   wire             ufm_disable_cmd;
+   reg                     ufm_enabled;
+   reg                     n_ufm_enabled;
+   wire             ufm_repeated_read;
+   wire             ufm_repeated_write;
+   
+
+
+   reg [7:0]             wb_dat_i ;
+   reg                     wb_stb_i ;
+   wire             wb_cyc_i =  wb_stb_i ;
+   reg [7:0]             wb_adr_i ;
+   reg                     wb_we_i  ;
+   wire [7:0]             wb_dat_o ;
+   wire             wb_ack_o ;
+
+   reg [7:0]             n_wb_dat_i ;
+   reg                     n_wb_stb_i ;
+   reg [7:0]             n_wb_adr_i ;
+   reg                     n_wb_we_i  ;
+   reg                     n_busy;
+   reg                     n_error;
+   reg [7:0]             c_state ,n_state;
+   reg                     efb_flag,n_efb_flag;
+   reg [7:0]             sm_wr_data;
+   reg [3:0]             sm_addr;
+   reg                     sm_ce;
+   reg                     sm_we;
+   reg [4:0]             count;
+   reg                     sm_addr_MSB;
+   reg [7:0]             sm_rd_data;
+
+
+   reg [7:0]             n_data_frm_ufm;
+   reg [3:0]             n_addr_ufm;
+   reg                     n_clk_en_ufm;
+   reg                     n_wr_en_ufm;
+   reg [4:0]             n_count;
+   reg                     n_ufm_addr_MSB;
+
+   wire [7:0]  cmd_read;
+   wire [7:0]  cmd_erase;
+   wire [7:0]  cmd_program;
+   wire [7:0]  cmd_select_sector;
+   wire [12:0] real_address;
+   
+   
+   PUR PUR_INST   (.PUR(1'b1));
+   GSR GSR_INST   (.GSR(1'b1));
+
+   flash inst1 (        .wb_clk_i(clk_i ),                                        // EFB with UFM enabled
+                        .wb_rst_i(!rst_n ),
+                        .wb_cyc_i(wb_cyc_i ),
+                        .wb_stb_i(wb_stb_i ), 
+                        .wb_we_i(wb_we_i ),
+                        .wb_adr_i(wb_adr_i), 
+                        .wb_dat_i(wb_dat_i ), 
+                        .wb_dat_o(wb_dat_o ), 
+                        .wb_ack_o(wb_ack_o ),
+                        .wbc_ufm_irq( )
+                        );
+   
+   // flashram inst2 (        .DataInA(sm_wr_data ),                                        // True dual port RAM. Port A controlled by internal SM and port B controlled by user.
+     //                                 .DataInB(mem_wr_data ), 
+   //                                 .AddressA({sm_addr_MSB,sm_addr} ), 
+   //                                 .AddressB({!sm_addr_MSB,mem_addr} ), 
+   //                                 .ClockA(clk_i ), 
+   //                                 .ClockB(mem_clk ), 
+   //                                 .ClockEnA(sm_ce ), 
+   //                                 .ClockEnB(mem_ce ), 
+   //                                 .WrA(sm_we ), 
+   //                                 .WrB(mem_we ), 
+   //                                 .ResetA(!rst_n ), 
+   //                                 .ResetB(!rst_n ), 
+   //                                 .QA(sm_rd_data ), 
+   //                                 .QB(mem_rd_data ));                                
+
+
+   always @ (*)
+     begin
+        sm_rd_data <= mem_rd_data;
+        mem_we <= sm_we;
+        mem_ce <= sm_ce;
+        mem_clk <= clk_i;
+        mem_addr <= sm_addr;
+        mem_wr_data <= sm_wr_data;
+     end
+   
+   assign ufm_enable_cmd = (cmd == 3'b100) ? 1'b1 : 1'b0 ;
+   assign ufm_read_cmd = ((cmd == 3'b000) || (cmd == 3'b001)) ? 1'b1 : 1'b0 ;
+   assign ufm_write_cmd = ((cmd == 3'b010) || (cmd == 3'b011)) ? 1'b1 : 1'b0 ;
+   assign ufm_erase_cmd = (cmd == 3'b111) ? 1'b1 : 1'b0 ;
+   assign ufm_disable_cmd = (cmd == 3'b101) ? 1'b1 : 1'b0 ;
+   assign ufm_repeated_read = (cmd == 3'b001) ? 1'b1 : 1'b0 ;
+   assign ufm_repeated_write = (cmd == 3'b011) ? 1'b1 : 1'b0 ;
+
+
+
+  assign cmd_read    = (select_cfg == 1'b0)? `CMD_UFM_READ : `CMD_CFG_READ ;  
+  assign cmd_erase   = (select_cfg == 1'b0)? `CMD_UFM_ERASE : `CMD_CFG_ERASE ;  
+  assign cmd_program = (select_cfg == 1'b0)? `CMD_UFM_PROGRAM : `CMD_CFG_PROGRAM ;  
+//  assign real_address= (ufm_page[12:10] == 3'b111)? {3'b000,ufm_page[9:0]} : ufm_page ;  
+  assign cmd_select_sector = (select_cfg == 1'b0)? 8'h40 : 8'h00 ;
+    
+
+   always @ (posedge clk_i or negedge rst_n)                        // generate clk enable and write enable signals for port A of the DPRAM
+     begin
+        if(!rst_n)
+          begin
+             sm_ce <= 1'b0;
+             sm_we <= 1'b0;
+          end
+        else if (((c_state == `state58) && (n_state == `state59))  || ((c_state == `state51)))                        
+          begin
+             sm_ce <= 1'b0;
+             sm_we <= 1'b0;
+          end
+        else if ((n_state == `state58) || ((c_state == `state50) && (n_state == `state51)))                
+          begin
+             sm_ce <= 1'b1;
+             if (ufm_read_cmd)
+               sm_we <= 1'b1;
+             else
+               sm_we <= 1'b0;
+          end
+        else 
+          begin
+             sm_ce <= 1'b0;
+             sm_we <= 1'b0;
+          end
+     end
+   
+   
+   always @ (posedge clk_i or negedge rst_n)
+     begin 
+        if(!rst_n)
+          begin 
+             wb_dat_i <= 8'h00;
+             wb_stb_i <= 1'b0 ;
+             wb_adr_i <= 8'h00;
+             wb_we_i  <= 1'b0;   
+          end   
+        else 
+          begin 
+             wb_dat_i <=  n_wb_dat_i;
+             wb_stb_i <=  #0.1 n_wb_stb_i;
+             wb_adr_i <=  n_wb_adr_i;
+             wb_we_i  <=  n_wb_we_i ;
+
+          end 
+     end 
+
+   always @ (posedge clk_i or negedge rst_n)
+     begin 
+        if(!rst_n) begin 
+           c_state  <= 10'h000;
+           BUSY     <= 1'b1;
+           efb_flag <= 1'b0 ;
+           ERR           <= 1'b0;
+           ufm_enabled <= 1'b0;
+           sm_wr_data <= 8'h00;
+           sm_addr <= 4'b0000;
+           count <= 4'hF;
+           sm_addr_MSB <= 1'b0;
+        end  
+        else begin  
+           c_state  <= n_state   ;
+           BUSY     <= n_busy;
+           efb_flag <= n_efb_flag;
+           ERR           <= n_error;
+           ufm_enabled <= n_ufm_enabled;
+           sm_wr_data <= n_data_frm_ufm;
+           sm_addr <= n_addr_ufm;
+           count <= n_count;
+           sm_addr_MSB <= n_ufm_addr_MSB;
+        end  
+     end
+   
+   
+   
+   always @ (*)
+     begin
+        n_state = c_state;
+        n_efb_flag   =  1'b0 ;
+        n_busy  = BUSY;
+        n_error = ERR;
+        n_ufm_enabled = ufm_enabled;
+        n_data_frm_ufm = sm_wr_data;
+        n_addr_ufm = sm_addr;
+        n_clk_en_ufm = sm_ce;
+        n_wr_en_ufm = sm_we;
+        n_count = count;
+        n_ufm_addr_MSB = sm_addr_MSB;
+        n_wb_dat_i = `ALL_ZERO ;
+        n_wb_adr_i = `ALL_ZERO ;
+        n_wb_we_i =  `LOW ;
+        n_wb_stb_i = `LOW ;
+        n_efb_flag = `LOW ;         
+        case (c_state)
+          
+          `state0 : begin
+             n_busy     =  1'b1;
+             n_error    =  1'b0;
+             n_ufm_enabled = 1'b0;
+             n_state    =  `state1;                                        // (state1 - state8)--check if UFM is busy and deassert BUSY flag if free.
+          end
+          
+          `state1: begin // enable WB-UFM interface
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state2;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR;
+                n_wb_dat_i = 8'h80;
+                n_wb_stb_i = `HIGH ; 
+                n_efb_flag   =  1'b1 ;
+             end
+          end
+          
+          
+          `state2: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state3;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = `CMD_CHECK_BUSY_FLAG;
+                n_wb_stb_i = `HIGH ; 
+                n_efb_flag   =  1'b1 ;
+             end
+          end
+          
+          
+          `state3: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state4;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ;
+                n_efb_flag   =  1'b1 ;                   
+             end
+          end
+          
+          
+          `state4: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state5;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state5: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state6;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_efb_flag   =  1'b1 ;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ; 
+                n_efb_flag   =  1'b1 ;
+             end
+          end
+          
+          
+          `state6: begin // Return Back to State 2
+             if (wb_ack_o && efb_flag) begin
+                if(wb_dat_o & (8'h80) )
+                  n_state = `state7;
+                else
+                  n_state = `state8;
+             end
+             else begin
+                n_wb_we_i =  `READ_STATUS;
+                n_wb_adr_i = `CFGRXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ;
+                n_efb_flag   =  1'b1 ;                   
+             end
+          end
+          
+          `state7: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state1;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGCR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ;
+                n_busy     =  1'b1;                   
+             end
+          end         
+          
+          `state8: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_busy     =  1'b0;
+                n_state = `state9;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGCR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ;
+                n_busy     =  1'b1;                   
+             end
+          end
+          
+          `state9: begin
+             if (GO)
+               begin
+                  n_busy     =  1'b1;
+                  n_error    =  1'b0;
+                  if (ufm_enabled && ufm_write_cmd)
+                    n_ufm_addr_MSB = !sm_addr_MSB;        
+                  n_state    =  `state10;
+               end
+             else
+               begin
+                  n_wb_dat_i = `ALL_ZERO ;
+                  n_wb_adr_i = `ALL_ZERO ;
+                  n_wb_we_i =  `LOW ;
+                  n_wb_stb_i = `LOW ;
+                  n_busy     =  1'b0;
+                  n_error    =  ERR;
+               end
+          end
+          
+          
+          `state10: begin         
+             if(ufm_enable_cmd)                                        // enable UFM   
+               n_state    =  `state11;
+             else if (ufm_enabled)begin                        // decode command only if UFM is already enabled
+                if (ufm_read_cmd)
+                  n_state    =  `state35;
+                else if (ufm_write_cmd)
+                  n_state    =  `state35;
+                else if (ufm_erase_cmd)
+                  n_state    =  `state17;
+                else if (ufm_disable_cmd)
+                  n_state    =  `state23;
+             end
+             else begin                                                        // set ERR if a command is sent when UFM is disabled and go to previous state and wait for GO
+                n_busy     =  1'b0;
+                n_error    =  1'b1;
+                n_state    =  `state9;
+             end
+          end        
+          
+          `state11: begin                                                         //  (state11 - state16) enable UFM        
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state12;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR;
+                n_efb_flag   =  1'b1 ;
+                n_wb_dat_i = 8'h80;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state12: begin // enable configuration
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state13;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = `CMD_ENABLE_INTERFACE;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state13: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state14;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h08;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state14: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state15;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_efb_flag   =  1'b1 ;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state15: begin //                                                 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state16;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ;                   
+             end
+          end
+          
+          
+          `state16: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_ufm_enabled = 1'b1;
+                 n_state = `state1;                                // check for busy flag after enabling UFM
+             end
+             else begin
+                n_efb_flag   =  1'b1 ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR ;
+                n_wb_dat_i = 8'h00;
+                n_busy     =  1'b1;
+                n_wb_stb_i = `HIGH ;
+                n_ufm_enabled = 1'b0;                   
+             end
+          end 
+          
+          
+          `state17: begin                                                         // (state17- state22) erase UFM
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state18;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR;
+                n_efb_flag   =  1'b1 ;
+                n_wb_dat_i = 8'h80;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state18: begin 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state19;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = cmd_erase;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state19: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state20;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h04;           //JM added for 0xE to erase CFG Flash
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state20: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state21;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_efb_flag   =  1'b1 ;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state21: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state22;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          `state22: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state1;                        // check for busy flag after erasing UFM
+             end
+             else begin
+                n_efb_flag   =  1'b1 ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR ;
+                n_wb_dat_i = 8'h00;
+                n_busy     =  1'b1;
+                n_wb_stb_i = `HIGH ;                   
+             end
+          end 
+
+          
+          `state23: begin // open frame                        // (state23 - state 32) disable UFM
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state24;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR;
+                n_efb_flag   =  1'b1 ;
+                n_wb_dat_i = 8'h80;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state24: begin // disable configuration
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state25;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = `CMD_DISABLE_INTERFACE;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state25: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state26;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state26: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state27;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_efb_flag   =  1'b1 ;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state27: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state28;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          `state28: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state29;
+             end
+             else begin
+                n_efb_flag   =  1'b1 ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR ;
+                n_wb_dat_i = 8'h00;
+                n_busy     =  1'b1;
+                n_wb_stb_i = `HIGH ;                   
+             end
+          end  
+          
+          `state29: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state30;
+             end
+             else begin
+                n_efb_flag   =  1'b1 ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR ;
+                n_wb_dat_i = 8'h80;
+                n_busy     =  1'b1;
+                n_wb_stb_i = `HIGH ;                   
+             end
+          end 
+          `state30: begin                                                                 //  bypass command
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state31;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = `CMD_BYPASS;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state31: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state32;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = `CMD_BYPASS;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state32: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state33;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = `CMD_BYPASS;
+                n_efb_flag   =  1'b1 ;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state33: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state34;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = `CMD_BYPASS;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state34: begin                                                                 // 
+             if (wb_ack_o && efb_flag) begin
+                n_busy     =  1'b0;
+                n_ufm_enabled = 1'b0;
+                n_state = `state9;
+             end
+             else begin
+                n_efb_flag   =  1'b1 ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR ;
+                n_wb_dat_i = 8'h00;
+                n_busy     =  1'b1;
+                n_wb_stb_i = `HIGH ;                   
+             end
+          end
+          
+
+          `state35: begin //                                                 (state35 - state60 ) UFM read/write operations
+             if (wb_ack_o && efb_flag) begin
+                if (ufm_repeated_read)
+                  n_state = `state46;
+                else if (ufm_repeated_write)
+                  n_state = `state54;
+                else
+                  n_state = `state36;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR;
+                n_wb_dat_i = 8'h80;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state36: begin                                                                 // Set UFM Page Address  
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state37;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = `CMD_SET_ADDRESS;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state37: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state38;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state38: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state39;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state39: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state40;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state40: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state41;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = cmd_select_sector;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state41: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state42;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state42: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state43;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+               // n_wb_dat_i = {3'b000,real_address[12:8]};
+               n_wb_dat_i = ufm_page[15:8] ;           
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state43: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state44;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+               // n_wb_dat_i = real_address[7:0];
+               n_wb_dat_i = ufm_page[7:0] ;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          `state44: begin // 
+             if (wb_ack_o && efb_flag) begin
+                if (ufm_write_cmd)
+                  n_state = `state53;
+                else
+                  n_state = `state45;
+             end
+             else begin
+                n_efb_flag   =  1'b1 ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR ;
+                n_wb_dat_i = 8'h00;
+                n_busy     =  1'b1;
+                n_wb_stb_i = `HIGH ;                   
+             end
+          end 
+            
+           `state45: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state46;
+             end
+             else begin
+                n_efb_flag   =  1'b1 ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR ;
+                n_wb_dat_i = 8'h80;
+                n_busy     =  1'b1;
+                n_wb_stb_i = `HIGH ;                   
+             end
+          end           
+          
+          `state46: begin // Read Operation
+             if (wb_ack_o && efb_flag) begin
+                n_count = READ_DELAY;
+                n_state = `stateRD_delay;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = cmd_read;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          `stateRD_delay: begin
+             if (count == 0)
+               n_state = `state47;
+             else begin
+                n_count = count - 1;
+             end
+          end
+          
+          `state47: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state48;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h10;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state48: begin // 
+             if (wb_ack_o && efb_flag)
+               n_state = `state49;
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state49: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_count = 5'b10000;
+                n_addr_ufm = 4'h0;
+                n_clk_en_ufm = 1'b1;
+                n_state = `state50;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h01;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+
+
+          `state50: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_count = count - 1;
+                n_data_frm_ufm = wb_dat_o;
+                n_state = `state51;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `READ_DATA;
+                n_wb_adr_i = `CFGRXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ;
+             end
+          end                 
+
+          `state51: begin // 
+             n_addr_ufm = sm_addr + 1;
+             if (count == 0)
+               n_state = `state52;
+             else begin
+                n_state = `state50;
+             end
+          end
+                 
+          
+          `state52: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_ufm_addr_MSB = !sm_addr_MSB;
+                n_busy     =  1'b0;
+                n_state = `state9;
+             end
+             else begin
+                n_wb_we_i =  `WRITE;
+                n_efb_flag   =  1'b1 ;
+                n_wb_adr_i = `CFGCR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ;
+                n_busy     =  1'b1;                   
+             end
+          end        
+          
+             `state53: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state54;
+             end
+             else begin
+                n_efb_flag   =  1'b1 ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR ;
+                n_wb_dat_i = 8'h80;
+                n_busy     =  1'b1;
+                n_wb_stb_i = `HIGH ;                   
+             end
+          end
+          `state54: begin // Write Operation
+             if (wb_ack_o && efb_flag) begin
+                     n_state = `state55;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = cmd_program;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state55: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state56;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state56: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state57;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h00;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state57: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_count = 5'b10000;
+                n_addr_ufm = 4'h0;
+                n_clk_en_ufm = 1'b1;
+                n_wr_en_ufm = 1'b0;
+                n_state = `state58;
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = 8'h01;
+                n_wb_stb_i = `HIGH ; 
+             end
+          end
+          
+          
+          `state58: begin // 
+             n_count = count - 1;
+             n_state = `state59;
+          end
+          
+          `state59: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_addr_ufm = sm_addr + 1;
+                if (count == 0)
+                  n_state = `state60;                                        
+                else begin
+                   n_state = `state58;
+                end
+             end
+             else begin
+                n_efb_flag = `HIGH ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGTXDR;
+                n_wb_dat_i = sm_rd_data;
+                n_wb_stb_i = `HIGH ;
+             end
+          end        
+          
+          `state60: begin // 
+             if (wb_ack_o && efb_flag) begin
+                n_state = `state1;
+             end
+             else begin
+                n_efb_flag   =  1'b1 ;
+                n_wb_we_i =  `WRITE;
+                n_wb_adr_i = `CFGCR ;
+                n_wb_dat_i = 8'h00;
+                n_busy     =  1'b1;
+                n_wb_stb_i = `HIGH ;                   
+             end
+          end        
+        endcase
+     end
+   
+   
+   
+endmodule  
+
+
index b864057a43c106668ff3752e38db2d65f0b94456..74f7a4e1416b00ea5e3f1c2d32958f062437de8a 100644 (file)
 --
 -- SPI registers:
 --  0x4x : Mapped flash page (16 Bytes)
---  0x50 : Flash command (see Padiwa manual)
---         Bits 15-13 : Flash command
---         Bits 12-0  : Flash page
+--  0x50 : Flash command
+--         Mode=0: (see Padiwa manual)
+--           Bit 15-13 : Flash command
+--           Bit 12-0  : Flash page
+--         Mode=1:
+--           16 bit page adress
+--  0x51 : Flash command (Mode 1)
+--         Bit 3-1 : Contains the 3-bit flash command when in mode 1
+--         The command must be written before the page address and can be re-used
 --  0x5C : control register
 --         Bit 0 : Enable cfg flash
 --         Bit 1 : Flash error (read-only)
 --         Bit 2 : Flash busy (read-only)
 --         Bit 4 : Master start (starts unpacking = booting)
 --         Bit 5 : Master running (read-only)
+--         Bit 8 : Mode
+--                 0: Old padiwa 13 bit mode
+--                 1: New 16 bit mode
 --  0x5D : Bits 0/1: Flash memory read buswidth:
 --         00 : 8 Bit, 01 : 16 Bit, 11 : 32 Bit (if available)
 --         Bit 4: 0: Little Endian; 1: Big Endian
@@ -77,7 +86,8 @@ architecture arch of generic_flash_ctrl is
       clk_i : in std_logic;
       rst_n : in std_logic;
       cmd       : in std_logic_vector(2 downto 0);
-      ufm_page  : in std_logic_vector(12 downto 0);
+      ufm_page  : in std_logic_vector(15 downto 0);
+      select_cfg : in std_logic;
       GO        : in std_logic;
       BUSY      : out std_logic;
       ERR       : out std_logic;
@@ -105,13 +115,17 @@ architecture arch of generic_flash_ctrl is
   signal flashram_data_o : std_logic_vector(7 downto 0);
 
   signal flash_command : std_logic_vector(2 downto 0);
+  signal flash_command_register : std_logic_vector(2 downto 0) := "000";
   signal spi_flash_command : std_logic_vector(2 downto 0);
-  signal flash_page    : std_logic_vector(12 downto 0);
-  signal spi_flash_page    : std_logic_vector(12 downto 0);
+  signal flash_page    : std_logic_vector(15 downto 0);
+  signal raw_flash_page    : std_logic_vector(15 downto 0);
+  signal spi_flash_page    : std_logic_vector(15 downto 0);
   signal flash_go      : std_logic;
   signal spi_flash_go      : std_logic;
   signal flash_busy    : std_logic;
   signal flash_err     : std_logic;
+  signal raw_select_cfg : std_logic;
+  signal flash_mode : std_logic := '0';
   
   signal ram_write_i : std_logic;
   signal ram_data_i  : std_logic_vector(7 downto 0);
@@ -167,13 +181,14 @@ begin
 
   THE_FLASH : UFM_WB
     port map(
-      clk_i     => CLK_f,
-      rst_n     => not RESET,
-      cmd       => flash_command,
-      ufm_page  => flash_page,
-      GO        => flash_go,
-      BUSY      => flash_busy,
-      ERR       => flash_err,
+      clk_i      => CLK_f,
+      rst_n      => not RESET,
+      cmd        => flash_command,
+      ufm_page   => raw_flash_page,
+      select_cfg => raw_select_cfg,
+      GO         => flash_go,
+      BUSY       => flash_busy,
+      ERR        => flash_err,
       mem_clk    => open,
       mem_we      => flashram_write_i,
       mem_ce      => flashram_cen_i,
@@ -190,6 +205,22 @@ begin
   SPI_READY_OUT <= reg_SPI_READY_OUT;
 
   LOC_BUSY_OUT  <= SPI_BUSY_IN;
+
+MODE_SELECTOR : process (flash_mode, flash_page, enable_cfg_flash)
+begin
+  if (flash_mode = '0') then
+    raw_flash_page(12 downto 0)  <= flash_page(12 downto 0);
+    raw_flash_page(15 downto 13) <= "000";
+    raw_select_cfg <= '1';
+    if (flash_page(12 downto 10) = "111") then
+      raw_select_cfg <= '0';
+      raw_flash_page(12 downto 10) <= "000";
+    end if;
+  else
+    raw_flash_page <= flash_page;
+    raw_select_cfg <= enable_cfg_flash;
+  end if;
+end process;                          
   
 PROC_SELECTOR : process begin
   wait until rising_edge(clk_l);
@@ -230,19 +261,27 @@ PROC_SELECTOR : process begin
       reg_LOC_WRITE_OUT <= '0';
       enable_cfg_flash <= SPI_DATA_IN(0);
       master_start_reg <= SPI_DATA_IN(4);
+      flash_mode       <= SPI_DATA_IN(8);
     elsif (SPI_ADDR_IN(7 downto 0) = x"5d") then
       reg_LOC_WRITE_OUT <= '0';
       memreg <= SPI_DATA_IN;
     elsif (SPI_ADDR_IN(7 downto 0) = x"5f") then
       reg_LOC_WRITE_OUT <= '0';
       testreg <= SPI_DATA_IN;
+    elsif (SPI_ADDR_IN(7 downto 0) = x"51") then
+      flash_command_register <= SPI_DATA_IN(3 downto 1);
     elsif (SPI_ADDR_IN(7 downto 0) = x"50") then
       reg_LOC_WRITE_OUT <= '0';
-      spi_flash_command <= SPI_DATA_IN(15 downto 13);
-      if (enable_cfg_flash = '1') then
-        spi_flash_page <= SPI_DATA_IN(12 downto 0);
+      if (flash_mode = '0') then
+        spi_flash_command <= SPI_DATA_IN(15 downto 13);
+        if (enable_cfg_flash = '1') then
+          spi_flash_page <= "000" & SPI_DATA_IN(12 downto 0);
+        else
+          spi_flash_page <= "000111" & SPI_DATA_IN(9 downto 0);
+        end if;
       else
-        spi_flash_page <= "111" & SPI_DATA_IN(9 downto 0);
+        spi_flash_command <= flash_command_register;
+        spi_flash_page <= SPI_DATA_IN(15 downto 0);
       end if;
       spi_flash_go <= '1';
     end if;
@@ -340,11 +379,16 @@ PROC_SELECTOR : process begin
       reg_SPI_READY_OUT <= '0';
       spi_ram_addr_i <= SPI_ADDR_IN(3 downto 0); -- prepare nibble1
       burst_counter <= memreg(11 downto 8);
+    elsif (SPI_ADDR_IN(7 downto 0) = x"51") then
+      reg_LOC_READ_OUT  <= '0';
+      reg_SPI_READY_OUT <= '1';
+      reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 0) <= (others => '0');
+      reg_SPI_DATA_OUT(2 downto 0) <= flash_command_register;
     elsif (SPI_ADDR_IN(7 downto 0) = x"5C") then
       reg_LOC_READ_OUT  <= '0';
       reg_SPI_READY_OUT <= '1';
       reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 0) <= (others => '0');
-      reg_SPI_DATA_OUT(15 downto 0) <= x"00" & "0" & auto_reset & master_running & master_start_reg & '0' & flash_busy & flash_err & enable_cfg_flash;
+      reg_SPI_DATA_OUT(15 downto 0) <= x"0" & "000" & flash_mode & '0' & auto_reset & master_running & master_start_reg & '0' & flash_busy & flash_err & enable_cfg_flash;
     elsif (SPI_ADDR_IN(7 downto 0) = x"5d") then
       reg_LOC_READ_OUT  <= '0';
       reg_SPI_READY_OUT <= '1';
@@ -370,7 +414,7 @@ end process;
 master_running <= '0' when state = IDLE else '1';
 ram_addr_i <= master_word_counter when master_running = '1' else spi_ram_addr_i;
 flash_go <= master_flash_go when master_running = '1' else spi_flash_go;
-flash_page <= master_flash_page when master_running = '1' else spi_flash_page;
+flash_page <= ("000" & master_flash_page) when master_running = '1' else spi_flash_page;
 flash_command <= master_flash_command when master_running = '1' else spi_flash_command;
 
 state_machine :  process (clk_l)
@@ -390,7 +434,7 @@ begin
             
     case state is
       when IDLE =>
-        if (master_start_reg = '1' or auto_reset = '1') then
+        if ((master_start_reg = '1' or auto_reset = '1') and (flash_mode = '0')) then
           state <= Start;
           clean_master_start_reg <= '1';
           master_DATA_OUT <= (others => '0');