--- /dev/null
+// --------------------------------------------------------------------
+// >>>>>>>>>>>>>>>>>>>>>>>>> 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
+
+
--
-- 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
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;
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);
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,
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);
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;
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';
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)
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');