The main changes included are: - Variant-dependent pin-out instantiation. - Update clocking scheme in top level file to include XO3 PLL - Add ability to shift outgoing data for the GPIO communication interface with the X410 FPGA. - Include project files required to build the XO3 variant of the ZBX CPLD. - Add build flow for Lattice Diamond designs. - Add ability to build XO3 variant of ZBX CPLD. Original-commit: 2c7813acb21383f302353a1b6cf57f0946fa0b6b
1066 lines
50 KiB
Verilog
1066 lines
50 KiB
Verilog
//
|
|
// Copyright 2021 Ettus Research, A National Instruments Brand
|
|
//
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
//
|
|
// Module: reconfig_engine
|
|
//
|
|
// Description:
|
|
//
|
|
// This file implements the registers and the state machine to interface with
|
|
// Intel's IP for the Max 10 FPGA that allows in-field updates to the primary
|
|
// FPGA image. This state machine has been designed to provide a level of
|
|
// abstraction between the register interface provided to user and the
|
|
// details of interfacing with Intel's On-Chip Flash IP block. The user
|
|
// simply needs to instruct this state machine to enable/disable write
|
|
// protection and perform read/write/erase operations accordingly to load and
|
|
// verify a new primary FPGA image. Since the purpose of this file is to
|
|
// allow modification to an FPGA image care has been taken to mitigate data
|
|
// corruption.
|
|
//
|
|
// The interface to Intel's On-Chip Flash IP block implemented in this file
|
|
// is based on the information found in the Max 10 User Flash Memory User
|
|
// Guide found at the link below.
|
|
//
|
|
// https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/hb/max-10/ug_m10_ufm.pdf
|
|
//
|
|
// Parameters:
|
|
//
|
|
// BASE_ADDRESS : Base address for CtrlPort registers.
|
|
// NUM_ADDRESSES : Number of bytes of address space to use.
|
|
// MEM_INIT : Memory initialization enabled. Set to 0 if MAX10 internal
|
|
// configuration set to single compressed image. Set to 1 if
|
|
// MAX10 internal configuration set to single compressed
|
|
// image with memory initialization.
|
|
//
|
|
|
|
`default_nettype none
|
|
|
|
|
|
module reconfig_engine #(
|
|
parameter BASE_ADDRESS = 0,
|
|
parameter NUM_ADDRESSES = 32,
|
|
parameter MEM_INIT = 0
|
|
) (
|
|
input wire ctrlport_clk,
|
|
input wire ctrlport_rst,
|
|
|
|
/// Request
|
|
input wire s_ctrlport_req_wr,
|
|
input wire s_ctrlport_req_rd,
|
|
input wire [19:0] s_ctrlport_req_addr,
|
|
input wire [31:0] s_ctrlport_req_data,
|
|
// Response
|
|
output reg s_ctrlport_resp_ack,
|
|
output reg [ 1:0] s_ctrlport_resp_status,
|
|
output reg [31:0] s_ctrlport_resp_data,
|
|
|
|
// Interface to On-Chip Flash IP
|
|
output reg csr_addr,
|
|
output reg csr_read,
|
|
output reg [31:0] csr_writedata,
|
|
output reg csr_write,
|
|
input wire [31:0] csr_readdata,
|
|
output reg [16:0] data_addr,
|
|
output reg data_read,
|
|
output reg [31:0] data_writedata,
|
|
output reg data_write,
|
|
input wire [31:0] data_readdata,
|
|
input wire data_waitrequest,
|
|
input wire data_readdatavalid
|
|
);
|
|
|
|
`include "regmap/reconfig_regmap_utils.vh"
|
|
`include "../../../lib/rfnoc/core/ctrlport.vh"
|
|
|
|
// Check MAX10 variant target (10M04, 10M08 or XO3)
|
|
`ifdef VARIANT_10M04
|
|
localparam FLASH_PRIMARY_IMAGE_START_ADDR_MEM_INIT = FLASH_PRIMARY_IMAGE_START_ADDR_MEM_INIT_10M04;
|
|
localparam FLASH_PRIMARY_IMAGE_START_ADDR = FLASH_PRIMARY_IMAGE_START_ADDR_10M04;
|
|
localparam FLASH_PRIMARY_IMAGE_END_ADDR = FLASH_PRIMARY_IMAGE_END_ADDR_10M04;
|
|
localparam CFM0_WP_OFFSET_MSB = 26; // From Max 10 Flash Memory User Guide.
|
|
localparam CFM0_WP_OFFSET_LSB = 24; // From Max 10 Flash Memory User Guide.
|
|
`elsif VARIANT_10M08
|
|
localparam FLASH_PRIMARY_IMAGE_START_ADDR_MEM_INIT = FLASH_PRIMARY_IMAGE_START_ADDR_MEM_INIT_10M08;
|
|
localparam FLASH_PRIMARY_IMAGE_START_ADDR = FLASH_PRIMARY_IMAGE_START_ADDR_10M08;
|
|
localparam FLASH_PRIMARY_IMAGE_END_ADDR = FLASH_PRIMARY_IMAGE_END_ADDR_10M08;
|
|
localparam CFM0_WP_OFFSET_MSB = 27; // From Max 10 Flash Memory User Guide.
|
|
localparam CFM0_WP_OFFSET_LSB = 25; // From Max 10 Flash Memory User Guide.
|
|
// The reconfiguration engine via flash is not supported in the XO3 variant.
|
|
`elsif VARIANT_XO3
|
|
localparam FLASH_PRIMARY_IMAGE_START_ADDR_MEM_INIT = 0;
|
|
localparam FLASH_PRIMARY_IMAGE_START_ADDR = 0;
|
|
localparam FLASH_PRIMARY_IMAGE_END_ADDR = 0;
|
|
localparam CFM0_WP_OFFSET_MSB = 0;
|
|
localparam CFM0_WP_OFFSET_LSB = 0;
|
|
`else
|
|
ERROR_MAX10_variant_must_be_defined();
|
|
localparam FLASH_PRIMARY_IMAGE_START_ADDR_MEM_INIT = FLASH_PRIMARY_IMAGE_START_ADDR_MEM_INIT_10M04;
|
|
localparam FLASH_PRIMARY_IMAGE_START_ADDR = FLASH_PRIMARY_IMAGE_START_ADDR_10M04;
|
|
localparam FLASH_PRIMARY_IMAGE_END_ADDR = FLASH_PRIMARY_IMAGE_END_ADDR_10M04;
|
|
localparam CFM0_WP_OFFSET_MSB = 26; // From Max 10 Flash Memory User Guide.
|
|
localparam CFM0_WP_OFFSET_LSB = 24; // From Max 10 Flash Memory User Guide.
|
|
`endif
|
|
|
|
|
|
//----------------------------------------------------------
|
|
// Flash Interface between Registers and State Machine
|
|
//----------------------------------------------------------
|
|
|
|
// Flash Data Interface
|
|
reg [16:0] flash_addr = 0;
|
|
reg [31:0] flash_write_data = 0;
|
|
reg [31:0] flash_read_data;
|
|
|
|
// Flash Control Interface - Control
|
|
reg flash_read_stb = 1'b0;
|
|
reg flash_write_stb = 1'b0;
|
|
reg flash_erase_stb = 1'b0;
|
|
reg flash_enable_wp_stb = 1'b0;
|
|
reg flash_disable_wp_stb = 1'b0;
|
|
reg [2:0] flash_sector = 3'b0;
|
|
|
|
// Flash Control Interface - Status
|
|
reg flash_wp_enabled;
|
|
reg flash_read_idle;
|
|
reg flash_write_idle;
|
|
reg flash_erase_idle;
|
|
reg flash_read_err;
|
|
reg flash_write_err;
|
|
reg flash_erase_err;
|
|
reg clear_flash_read_err_stb = 1'b0;
|
|
reg clear_flash_write_err_stb = 1'b0;
|
|
reg clear_flash_erase_err_stb = 1'b0;
|
|
|
|
//----------------------------------------------------------
|
|
// Address Calculation
|
|
//----------------------------------------------------------
|
|
|
|
wire address_in_range = (s_ctrlport_req_addr >= BASE_ADDRESS) &&
|
|
(s_ctrlport_req_addr < BASE_ADDRESS + NUM_ADDRESSES);
|
|
|
|
//----------------------------------------------------------
|
|
// Handling of ControlPort Requests
|
|
//----------------------------------------------------------
|
|
|
|
always @(posedge ctrlport_clk) begin
|
|
// Default assignments
|
|
s_ctrlport_resp_ack <= 1'b0;
|
|
|
|
flash_read_stb <= 1'b0;
|
|
flash_write_stb <= 1'b0;
|
|
flash_erase_stb <= 1'b0;
|
|
flash_enable_wp_stb <= 1'b0;
|
|
flash_disable_wp_stb <= 1'b0;
|
|
clear_flash_read_err_stb <= 1'b0;
|
|
clear_flash_write_err_stb <= 1'b0;
|
|
clear_flash_erase_err_stb <= 1'b0;
|
|
|
|
// Do not acknowledge on reset
|
|
if (ctrlport_rst) begin
|
|
s_ctrlport_resp_ack <= 1'b0;
|
|
s_ctrlport_resp_data <= {32{1'bx}};
|
|
s_ctrlport_resp_status <= CTRL_STS_OKAY;
|
|
|
|
// Write requests
|
|
end else begin
|
|
if (s_ctrlport_req_wr) begin
|
|
// Always issue an ack and no data
|
|
s_ctrlport_resp_ack <= 1'b1;
|
|
s_ctrlport_resp_data <= {32{1'bx}};
|
|
s_ctrlport_resp_status <= CTRL_STS_OKAY;
|
|
|
|
case (s_ctrlport_req_addr)
|
|
BASE_ADDRESS + FLASH_CONTROL_REG: begin
|
|
flash_read_stb <= s_ctrlport_req_data[FLASH_READ_STB];
|
|
flash_write_stb <= s_ctrlport_req_data[FLASH_WRITE_STB];
|
|
flash_erase_stb <= s_ctrlport_req_data[FLASH_ERASE_STB];
|
|
flash_enable_wp_stb <= s_ctrlport_req_data[FLASH_ENABLE_WP_STB];
|
|
flash_disable_wp_stb <= s_ctrlport_req_data[FLASH_DISABLE_WP_STB];
|
|
clear_flash_read_err_stb <= s_ctrlport_req_data[CLEAR_FLASH_READ_ERROR_STB];
|
|
clear_flash_write_err_stb <= s_ctrlport_req_data[CLEAR_FLASH_WRITE_ERROR_STB];
|
|
clear_flash_erase_err_stb <= s_ctrlport_req_data[CLEAR_FLASH_ERASE_ERROR_STB];
|
|
flash_sector <= s_ctrlport_req_data[FLASH_ERASE_SECTOR_MSB:FLASH_ERASE_SECTOR];
|
|
end
|
|
|
|
BASE_ADDRESS + FLASH_ADDR_REG: begin
|
|
flash_addr <= s_ctrlport_req_data[FLASH_ADDR_MSB:FLASH_ADDR];
|
|
end
|
|
|
|
BASE_ADDRESS + FLASH_WRITE_DATA_REG: begin
|
|
flash_write_data <= s_ctrlport_req_data[FLASH_WRITE_DATA_MSB:FLASH_WRITE_DATA];
|
|
end
|
|
|
|
// Error on undefined address
|
|
default: begin
|
|
if (address_in_range) begin
|
|
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
|
|
|
|
// No response if out of range
|
|
end else begin
|
|
s_ctrlport_resp_ack <= 1'b0;
|
|
end
|
|
end
|
|
endcase
|
|
|
|
// Read request
|
|
end else if (s_ctrlport_req_rd) begin
|
|
// Default assumption: valid request
|
|
s_ctrlport_resp_ack <= 1'b1;
|
|
s_ctrlport_resp_status <= CTRL_STS_OKAY;
|
|
|
|
case (s_ctrlport_req_addr)
|
|
BASE_ADDRESS + FLASH_STATUS_REG: begin
|
|
s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'b0}};
|
|
s_ctrlport_resp_data[FLASH_WP_ENABLED] <= flash_wp_enabled;
|
|
s_ctrlport_resp_data[FLASH_READ_IDLE] <= flash_read_idle;
|
|
s_ctrlport_resp_data[FLASH_READ_ERR] <= flash_read_err;
|
|
s_ctrlport_resp_data[FLASH_ERASE_IDLE] <= flash_erase_idle;
|
|
s_ctrlport_resp_data[FLASH_ERASE_ERR] <= flash_erase_err;
|
|
s_ctrlport_resp_data[FLASH_WRITE_IDLE] <= flash_write_idle;
|
|
s_ctrlport_resp_data[FLASH_WRITE_ERR] <= flash_write_err;
|
|
s_ctrlport_resp_data[FLASH_MEM_INIT_ENABLED] <= MEM_INIT ? 1'b1 : 1'b0;
|
|
end
|
|
|
|
BASE_ADDRESS + FLASH_ADDR_REG: begin
|
|
s_ctrlport_resp_data <= {CTRLPORT_DATA_W {1'b0}};
|
|
s_ctrlport_resp_data[FLASH_ADDR_MSB:FLASH_ADDR] <= flash_addr;
|
|
end
|
|
|
|
BASE_ADDRESS + FLASH_READ_DATA_REG: begin
|
|
s_ctrlport_resp_data <= flash_read_data;
|
|
end
|
|
|
|
BASE_ADDRESS + FLASH_CFM0_START_ADDR_REG: begin
|
|
s_ctrlport_resp_data <= MEM_INIT ? FLASH_PRIMARY_IMAGE_START_ADDR_MEM_INIT :
|
|
FLASH_PRIMARY_IMAGE_START_ADDR;
|
|
end
|
|
|
|
BASE_ADDRESS + FLASH_CFM0_END_ADDR_REG: begin
|
|
s_ctrlport_resp_data <= FLASH_PRIMARY_IMAGE_END_ADDR;
|
|
end
|
|
|
|
// Error on undefined address
|
|
default: begin
|
|
s_ctrlport_resp_data <= {32{1'bx}};
|
|
if (address_in_range) begin
|
|
s_ctrlport_resp_status <= CTRL_STS_CMDERR;
|
|
|
|
// No response if out of range
|
|
end else begin
|
|
s_ctrlport_resp_ack <= 1'b0;
|
|
end
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
end
|
|
|
|
//----------------------------------------------------------
|
|
// State Machine Constants
|
|
//----------------------------------------------------------
|
|
|
|
// Local state
|
|
localparam IDLE = 4'h0;
|
|
localparam WP_DISABLED = 4'h1;
|
|
localparam WAIT_FOR_READ_DATA_VALID = 4'h2;
|
|
localparam GET_READ_STATUS = 4'h3;
|
|
localparam CHECK_READ_STATUS = 4'h4;
|
|
localparam WAIT_FOR_WRITE_COMPLETE = 4'h5;
|
|
localparam GET_WRITE_STATUS = 4'h6;
|
|
localparam CHECK_WRITE_STATUS = 4'h7;
|
|
localparam ERASE_SECTOR = 4'h8;
|
|
localparam GET_ERASE_BUSY = 4'h9;
|
|
localparam CHECK_ERASE_BUSY = 4'hA;
|
|
localparam GET_ERASE_IDLE = 4'hB;
|
|
localparam CHECK_ERASE_IDLE = 4'hC;
|
|
|
|
// The Intel on-chip flash control interface has two registers, a Status
|
|
// Register at address 0 and a Control Register at address 1. The constants
|
|
// defined below identify fields and values of interest in each register.
|
|
// These are taken directly from the Max 10 Flash Memory User Guide.
|
|
localparam STATUS_REG_ADDR = 1'b0;
|
|
localparam STATUS_REG_BUSY_STATUS_MSB = 1;
|
|
localparam STATUS_REG_BUSY_STATUS_LSB = 0;
|
|
localparam STATUS_REG_IDLE = 2'b00;
|
|
localparam STATUS_REG_ERASE_BUSY = 2'b01;
|
|
localparam STATUS_REG_WRITE_BUSY = 2'b10;
|
|
localparam STATUS_REG_READ_BUSY = 2'b11;
|
|
localparam STATUS_REG_READ_STATUS = 2;
|
|
localparam STATUS_REG_WRITE_STATUS = 3;
|
|
localparam STATUS_REG_ERASE_STATUS = 4;
|
|
localparam OPERATION_FAILED = 0;
|
|
|
|
localparam CONTROL_REG_ADDR = 1'b1;
|
|
localparam SECTOR_ERASE_ADDR_MSB = 22;
|
|
localparam SECTOR_ERASE_ADDR_LSB = 20;
|
|
// CFM0_WP_OFFSET_MSB and CFM0_WP_OFFSET_LSB are MAX10 variant dependent.
|
|
localparam ENABLE_WP = MEM_INIT ? 3'b111 : 3'b100;
|
|
localparam DISABLE_WP = 3'b000;
|
|
|
|
//----------------------------------------------------------
|
|
// State Machine
|
|
//----------------------------------------------------------
|
|
|
|
reg [3:0] state = IDLE;
|
|
wire flash_no_errors_detected;
|
|
|
|
assign flash_no_errors_detected = ~(flash_read_err | flash_write_err | flash_erase_err);
|
|
|
|
always @(posedge ctrlport_clk) begin
|
|
if (ctrlport_rst) begin
|
|
state <= IDLE;
|
|
|
|
// Signals to config registers
|
|
flash_wp_enabled <= 1'b1;
|
|
flash_read_idle <= 1'b1;
|
|
flash_write_idle <= 1'b1;
|
|
flash_erase_idle <= 1'b1;
|
|
flash_read_err <= 1'b0;
|
|
flash_write_err <= 1'b0;
|
|
flash_erase_err <= 1'b0;
|
|
flash_read_data <= 32'b0;
|
|
|
|
// Signals to flash control interface
|
|
csr_addr <= 1'b0;
|
|
csr_writedata <= {32 {1'b1}};
|
|
csr_read <= 1'b0;
|
|
csr_write <= 1'b0;
|
|
|
|
// Signals to flash data interface
|
|
data_addr <= 17'b0;
|
|
data_writedata <= 32'b0;
|
|
data_read <= 1'b0;
|
|
data_write <= 1'b0;
|
|
end
|
|
// Rising edge clock
|
|
else begin
|
|
// Default values
|
|
csr_read <= 1'b0;
|
|
csr_write <= 1'b0;
|
|
csr_addr <= STATUS_REG_ADDR;
|
|
csr_writedata <= {32 {1'b1}};
|
|
|
|
data_read <= 1'b0;
|
|
data_write <= 1'b0;
|
|
|
|
// State handling
|
|
case(state)
|
|
|
|
// When in IDLE:
|
|
// * No operations are in progress and write protection is enabled.
|
|
// * Allowed transitions are to either read data from flash or
|
|
// disable write protection.
|
|
// * Transitions are only allowed if no error bits are asserted.
|
|
// * In the event both the *read_stb and *disable_wp_stb bits are
|
|
// asserted read operations take priority as these do not open the
|
|
// flash to modification.
|
|
// * Attempts to both enable and disable write protection
|
|
// simultaneously result in the state machine remaining in IDLE
|
|
// write protection enabled.
|
|
IDLE: begin
|
|
flash_wp_enabled <= 1'b1;
|
|
|
|
if (flash_read_stb && flash_no_errors_detected) begin
|
|
state <= WAIT_FOR_READ_DATA_VALID;
|
|
flash_read_idle <= 1'b0;
|
|
data_read <= 1'b1;
|
|
data_addr <= flash_addr;
|
|
end else if (flash_disable_wp_stb && ~flash_enable_wp_stb && flash_no_errors_detected) begin
|
|
state <= WP_DISABLED;
|
|
csr_write <= 1'b1;
|
|
csr_addr <= CONTROL_REG_ADDR;
|
|
csr_writedata[CFM0_WP_OFFSET_MSB:CFM0_WP_OFFSET_LSB] <= DISABLE_WP;
|
|
end
|
|
end
|
|
|
|
// Transition from WP_DISABLED when write protection is enabled or when
|
|
// write/erase operations are initiated. A few things to note:
|
|
// * Enabling write protection takes priority, regardless of what
|
|
// other control bits may be asserted simultaneously, followed by
|
|
// writes, and lastly erases.
|
|
// * The user should not strobe both the *write_stb and *erase_stb
|
|
// bits simultaneously, but if they do the state machine returns to
|
|
// IDLE (thereby enabling write protection) and the *write_err and
|
|
// *erase_err bits are asserted.
|
|
// * Performing a write or erase operation is only allowed from
|
|
// WP_DISABLED. This allows some mitigation against data corruption
|
|
// as multiple steps are required to change the data in the flash.
|
|
// First write protection must be disabled, and only then can the
|
|
// flash be erased or written.
|
|
WP_DISABLED: begin
|
|
flash_wp_enabled <= 1'b0;
|
|
|
|
if (flash_erase_stb && flash_write_stb) begin
|
|
flash_erase_err <= 1'b1;
|
|
flash_write_err <= 1'b1;
|
|
end
|
|
|
|
if (flash_enable_wp_stb || (flash_erase_stb && flash_write_stb)) begin
|
|
state <= IDLE;
|
|
csr_write <= 1'b1;
|
|
csr_addr <= CONTROL_REG_ADDR;
|
|
csr_writedata[CFM0_WP_OFFSET_MSB:CFM0_WP_OFFSET_LSB] <= ENABLE_WP;
|
|
end else if (flash_write_stb) begin
|
|
state <= WAIT_FOR_WRITE_COMPLETE;
|
|
flash_write_idle <= 1'b0;
|
|
data_write <= 1'b1;
|
|
data_writedata <= flash_write_data;
|
|
data_addr <= flash_addr;
|
|
end else if (flash_erase_stb) begin
|
|
state <= ERASE_SECTOR;
|
|
flash_erase_idle <= 1'b0;
|
|
csr_write <= 1'b1;
|
|
csr_addr <= CONTROL_REG_ADDR;
|
|
csr_writedata[CFM0_WP_OFFSET_MSB:CFM0_WP_OFFSET_LSB] <= DISABLE_WP;
|
|
csr_writedata[SECTOR_ERASE_ADDR_MSB:SECTOR_ERASE_ADDR_LSB] <= flash_sector;
|
|
end
|
|
end
|
|
|
|
|
|
// Read Flash
|
|
// --------------
|
|
// Per Intel's Max 10 User Flash Memory User Guide, the Read bit of the
|
|
// flash data interface should be pulsed for one clock cycle to start
|
|
// the read process from flash. This pulse occurs upon transition from
|
|
// IDLE to WAIT_FOR_READ_DATA_VALID. The state machine then waits in
|
|
// WAIT_FOR_READ_DATA_VALID until the flash data interface
|
|
// data_readdatavalid signal asserts, indicating the data is now valid.
|
|
// Intel's documentation does not provide guidance on the expected time
|
|
// for data_readdatavalid to assert. From simulation, however,
|
|
// data_readdatavalid asserts four clock cycles after the Read pulse
|
|
// ends. The data_readdatavalid signal from the flash data interface
|
|
// pulses for one clock cycle. Only during this pulse is the data valid.
|
|
WAIT_FOR_READ_DATA_VALID: begin
|
|
if (data_readdatavalid) begin
|
|
state <= GET_READ_STATUS;
|
|
flash_read_data <= data_readdata;
|
|
csr_read <= 1'b1;
|
|
end
|
|
end
|
|
|
|
// The data_readdatavalid signal determines when the read operation has
|
|
// completed in the flash data interface, but Intel's documentation
|
|
// does not indicate the relation of this bit to the 'busy' field in
|
|
// the flash control interface Status Register. To verify that the read
|
|
// operation is complete, the StatusRegister is polled until the 'busy'
|
|
// field indicates the flash is idle. This polling operation is
|
|
// implemented with CHECK_READ_STATUS below. GET_READ_STATUS exists to
|
|
// set the address of the flash control interface to the Status
|
|
// Register and pulse the read bit of the flash control interface.
|
|
// CHECK_READ_STATUS evaluates the resulting Status Register data and
|
|
// steer the state machine accordingly. See Figure 6 in Intel's Max 10
|
|
// User Flash Memory User Guide for a waveform on this request and
|
|
// check mechanism. Successful read operations result in the state
|
|
// machine returning to IDLE. Failing read operations assert the
|
|
// flash_read_err bit before returning to IDLE. From simulation, the
|
|
// 'busy' field returns to IDLE on the third read.
|
|
GET_READ_STATUS: begin
|
|
state <= CHECK_READ_STATUS;
|
|
// csr_read set in transactions into this state
|
|
// CSR address set as default assignment
|
|
end
|
|
CHECK_READ_STATUS: begin
|
|
if (csr_readdata[STATUS_REG_BUSY_STATUS_MSB:STATUS_REG_BUSY_STATUS_LSB] == STATUS_REG_IDLE) begin
|
|
state <= IDLE;
|
|
flash_read_idle <= 1'b1;
|
|
flash_read_err <= (csr_readdata[STATUS_REG_READ_STATUS] == OPERATION_FAILED) ? 1'b1 : 1'b0;
|
|
end else if (csr_readdata[STATUS_REG_BUSY_STATUS_MSB:STATUS_REG_BUSY_STATUS_LSB] == STATUS_REG_READ_BUSY) begin
|
|
state <= GET_READ_STATUS;
|
|
csr_read <= 1'b1;
|
|
end
|
|
end
|
|
|
|
|
|
// Write Flash
|
|
//---------------
|
|
// Per Intel's Max 10 User Flash Memory User Guide, the Write bit of
|
|
// the flash data interface should be asserted while maintaining
|
|
// address and data until the flash interface deasserts the
|
|
// data_waitrequest bit. Transition from WP_DISABLED to
|
|
// WAIT_FOR_WRITE_COMPLETE causes the write bit to assert and address
|
|
// and data to be set. The state machine remains in this state until
|
|
// the data_waitrequest bit deasserts. Per Intel's Max 10 User Flash
|
|
// Memory User Guide, the data_waitrequest signal is expected to
|
|
// deassert within 555 usec.
|
|
WAIT_FOR_WRITE_COMPLETE: begin
|
|
if (~data_waitrequest) begin
|
|
state <= GET_WRITE_STATUS;
|
|
csr_read <= 1'b1;
|
|
end else begin
|
|
// Flash writes require asserting the Write bit of the flash data
|
|
// interface until the write is complete.
|
|
data_write <= 1'b1;
|
|
end
|
|
end
|
|
|
|
// The data_waitrequest signal determines when the write operation has
|
|
// completed in the flash data interface, but Intel's documentation does
|
|
// not indicate the relation of this bit to the 'busy' field in the flash
|
|
// control interface Status Register. To verify that the write operation
|
|
// is complete the StatusRegister is polled until the 'busy' field
|
|
// indicates the flash is idle. This polling operation is implemented with
|
|
// GET_WRITE_STATUS and CHECK_WRITE_STATUS below, and follows the same
|
|
// methodology as the polling operation for reads described above with the
|
|
// following two changes:
|
|
// * Upon successful completion of a write operation the state
|
|
// machine returns to WP_DISABLED. This allows repeated writes of
|
|
// new data without having to disable/enable for each write.
|
|
// * When a failure is detected the state machine transitions to to
|
|
// IDLE thereby enabling write protection. Failure of a write is
|
|
// not expected. Write protection is enabled in the event of a
|
|
// failure to mitigate further data corruption.
|
|
GET_WRITE_STATUS: begin
|
|
state <= CHECK_WRITE_STATUS;
|
|
// csr_read set in transactions into this state
|
|
// CSR address set as default assignment
|
|
end
|
|
CHECK_WRITE_STATUS: begin
|
|
if (csr_readdata[STATUS_REG_BUSY_STATUS_MSB:STATUS_REG_BUSY_STATUS_LSB] == STATUS_REG_IDLE) begin
|
|
if (csr_readdata[STATUS_REG_WRITE_STATUS] == OPERATION_FAILED) begin
|
|
state <= IDLE;
|
|
csr_write <= 1'b1;
|
|
csr_addr <= CONTROL_REG_ADDR;
|
|
csr_writedata[CFM0_WP_OFFSET_MSB:CFM0_WP_OFFSET_LSB] <= ENABLE_WP;
|
|
end else begin // SUCCESS
|
|
state <= WP_DISABLED;
|
|
end
|
|
flash_write_idle <= 1'b1;
|
|
flash_write_err <= (csr_readdata[STATUS_REG_WRITE_STATUS] == OPERATION_FAILED) ? 1'b1 : 1'b0;
|
|
end else if (csr_readdata[STATUS_REG_BUSY_STATUS_MSB:STATUS_REG_BUSY_STATUS_LSB] == STATUS_REG_WRITE_BUSY) begin
|
|
state <= GET_WRITE_STATUS;
|
|
csr_read <= 1'b1;
|
|
end
|
|
end
|
|
|
|
// Erase Flash
|
|
//-------------
|
|
// Erasing the primary configuration image requires a single write to
|
|
// the flash control interface Control Register. Only one sector needs
|
|
// to be erased to erase the entire primary configuration image.
|
|
// Transition from WP_DISABLED to ERASE_SECTOR causes data to be
|
|
// written to the Control Register to erase this sector and pulse the
|
|
// flash control interface write bit.
|
|
ERASE_SECTOR: begin
|
|
state <= GET_ERASE_BUSY;
|
|
csr_read <= 1'b1;
|
|
end
|
|
|
|
// There is some latency between writing the Control Register and the
|
|
// 'busy' field of the flash control interface Status Register
|
|
// indicating the erase operation is in progress. After initiating the
|
|
// erase operation, GET_ERASE_BUSY and CHECK_ERASE_BUSY implement a
|
|
// polling operation to determine when the erase operation has started.
|
|
// GET_ERASE_BUSY exists to set the address of the flash control
|
|
// interface to the Status Register and pulse the read bit of the flash
|
|
// control interface. CHECK_ERASE_BUSY exists to evaluate the resulting
|
|
// Status Register data and steer the state machine accordingly. The
|
|
// polling operation continues until the 'busy' field indicates the
|
|
// erase operation is in progress. Intel's documentation does not
|
|
// indicate how long it takes for the Status Register to indicate the
|
|
// erase is in progress, but simulation shows the erase is in progress
|
|
// after the second read.
|
|
GET_ERASE_BUSY: begin
|
|
state <= CHECK_ERASE_BUSY;
|
|
// csr_read set in transactions into this state
|
|
// CSR address set as default assignment
|
|
end
|
|
CHECK_ERASE_BUSY: begin
|
|
if (csr_readdata[STATUS_REG_BUSY_STATUS_MSB:STATUS_REG_BUSY_STATUS_LSB] == STATUS_REG_ERASE_BUSY) begin
|
|
state <= GET_ERASE_IDLE;
|
|
csr_read <= 1'b1;
|
|
end else if (csr_readdata[STATUS_REG_BUSY_STATUS_MSB:STATUS_REG_BUSY_STATUS_LSB] == STATUS_REG_IDLE) begin
|
|
state <= GET_ERASE_BUSY;
|
|
csr_read <= 1'b1;
|
|
end
|
|
end
|
|
|
|
// Once the erase operation is in progress a second polling operation
|
|
// defined by GET_ERASE_IDLE and CHECK_ERASE_IDLE is implemented to
|
|
// determine when the operation has completed. This polling operation
|
|
// follows the same methodology as the polling operation for erase busy
|
|
// described above. Intel's documentation indicates that erase
|
|
// operations take a maximum of 350 msec.
|
|
GET_ERASE_IDLE: begin
|
|
state <= CHECK_ERASE_IDLE;
|
|
// csr_read set in transactions into this state
|
|
// CSR address set as default assignment
|
|
end
|
|
CHECK_ERASE_IDLE: begin
|
|
if (csr_readdata[STATUS_REG_BUSY_STATUS_MSB:STATUS_REG_BUSY_STATUS_LSB] == STATUS_REG_IDLE) begin
|
|
if (csr_readdata[STATUS_REG_ERASE_STATUS] == OPERATION_FAILED) begin
|
|
state <= IDLE;
|
|
csr_write <= 1'b1;
|
|
csr_addr <= CONTROL_REG_ADDR;
|
|
csr_writedata[CFM0_WP_OFFSET_MSB:CFM0_WP_OFFSET_LSB] <= ENABLE_WP;
|
|
end else begin // SUCCESS
|
|
state <= WP_DISABLED;
|
|
end
|
|
flash_erase_idle <= 1'b1;
|
|
flash_erase_err <= (csr_readdata[STATUS_REG_ERASE_STATUS] == OPERATION_FAILED) ? 1'b1 : 1'b0;
|
|
end else if (csr_readdata[STATUS_REG_BUSY_STATUS_MSB:STATUS_REG_BUSY_STATUS_LSB] == STATUS_REG_ERASE_BUSY) begin
|
|
state <= GET_ERASE_IDLE;
|
|
csr_read <= 1'b1;
|
|
end
|
|
end
|
|
|
|
// Default to IDLE in other cases
|
|
default: begin
|
|
state <= IDLE;
|
|
end
|
|
endcase
|
|
|
|
// Reset errors
|
|
if (clear_flash_read_err_stb) begin
|
|
flash_read_err <= 1'b0;
|
|
end
|
|
if (clear_flash_write_err_stb) begin
|
|
flash_write_err <= 1'b0;
|
|
end
|
|
if (clear_flash_erase_err_stb) begin
|
|
flash_erase_err <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule
|
|
|
|
|
|
`default_nettype wire
|
|
|
|
|
|
//XmlParse xml_on
|
|
//<regmap name="RECONFIG_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true">
|
|
// <group name="RECONFIG_REGS">
|
|
// <info>
|
|
// These registers are used to upload and verify a new primary image to the
|
|
// Max 10 FPGA on-chip flash when configured to support dual configuration
|
|
// images. The steps below outline the process of verifying/preparing the
|
|
// new image to be written, erasing the current image, writing the new
|
|
// image, and verifying the new image was successfully written.
|
|
// {p}{b}Prepare the data...{/b}
|
|
// {ol}{li}{p}The Max 10 FPGA build should generate a *cfm0_auto.rpd
|
|
// file The *.rpd file is a "raw programming
|
|
// data" file holding all data related to the
|
|
// configuration image (CFM0). There are two
|
|
// important items to note regarding the addresses.
|
|
// First the *rpd data uses {b}byte{/b} addresses.
|
|
// Second, the start/end addresses defined by
|
|
// FLASH_PRIMARY_IMAGE_ADDR_ENUM are 32-bit word addresses{/p}{/li}
|
|
// {li}{p}As a sanity check, verify the size of the raw
|
|
// programming data for CFM0 correspond to the address
|
|
// range of FLASH_PRIMARY_IMAGE_ADDR_ENUM. Do this by
|
|
// reading the values from FLASH_CFM0_START_ADDR_REG and
|
|
// FLASH_CFM0_END_ADDR, subtract both values, add one and
|
|
// multiply by four.
|
|
// {/p}{/li}
|
|
// {li}{p}Having passed the sanity check the *.rpd data must
|
|
// now be manipulated into the form required by Altera's
|
|
// on-chip flash IP. Two operations must be performed.
|
|
// First the data must be converted from bytes to 32-bit
|
|
// words. Second the bit order must be reversed. This is
|
|
// illustrated in in the following table which shows byte
|
|
// address and data from the *.rpd file compared to the
|
|
// word address and data to be written to the on-chip
|
|
// flash.
|
|
// {table border=1}
|
|
// {tr}{td}.Map Addr{/td}{td}.Map Data{/td}{td}Flash Addr{/td}{td}Flash Data{/td}{/tr}
|
|
// {tr}{td}0x2B800{/td}{td}0x01{/td}{td rowspan=4}0xAC00{/td}{td rowspan=4}0x8040C020{/td}{/tr}
|
|
// {tr}{td}0x2B801{/td}{td}0x02{/td}{/tr}
|
|
// {tr}{td}0x2B802{/td}{td}0x03{/td}{/tr}
|
|
// {tr}{td}0x2B803{/td}{td}0x04{/td}{/tr}
|
|
// {tr}{td}0x2B804{/td}{td}0x05{/td}{td rowspan=4}0xAC01{/td}{td rowspan=4}0xA060E010{/td}{/tr}
|
|
// {tr}{td}0x2B805{/td}{td}0x06{/td}{/tr}
|
|
// {tr}{td}0x2B806{/td}{td}0x07{/td}{/tr}
|
|
// {tr}{td}0x2B807{/td}{td}0x08{/td}{/tr}
|
|
// {/table}
|
|
// {/p}{/li}
|
|
// {li}{p}The resulting set of flash address data pairs should
|
|
// be used when writing FLASH_ADDR_REG and
|
|
// FLASH_WRITE_DATA_REG to update the CFM0 image.
|
|
// However, prior to writing the new image the old image
|
|
// must be erased.
|
|
// {/p}{/li}
|
|
// {/ol}
|
|
// {/p}
|
|
// {p}{b}Erase the current primary flash image...{/b}
|
|
// {ol}{p}{li}Read FLASH_STATUS_REG and verify no error bits are
|
|
// asserted and that all read, write, and erase operations
|
|
// are idle.{/p}{/li}
|
|
// {p}{li}Disable write protection of the flash by strobing the
|
|
// FLASH_DISABLE_WP_STB bit of FLASH_CONTROL_REG.
|
|
// {/p}{/li}
|
|
// {p}{li}Verify write protection is disabled and no errors are
|
|
// present by reading FLASH_STATUS_REG.{/p}{/li}
|
|
// {p}{li}Initiate the erase operation by setting
|
|
// @.FLASH_ERASE_SECTOR and strobing FLASH_ERASE_STB of
|
|
// FLASH_CONTROL_REG.{/p}{/li}
|
|
// {p}{li}Poll the FLASH_ERASE_IDLE bit of
|
|
// FLASH_STATUS_REG until it de-asserts indicating the
|
|
// erase operation is complete, then verify the operation
|
|
// was successful by checking that the FLASH_ERASE_ERR
|
|
// bit is de-asserted. Erase operations are expected to
|
|
// take a maximum of 350 msec. Upon completion of the erase
|
|
// operation write protection will remain disabled.
|
|
// {/p}{/li}
|
|
// {p}{li}Erase additional sectors as required (see
|
|
// @.FLASH_ERASE_SECTOR for details) by restarting with first
|
|
// step.{/p}{/li}
|
|
// {/ol}
|
|
// {/p}
|
|
// {p}{b}Write the new primary flash image...{/b}
|
|
// {ol}{p}{li}Read FLASH_STATUS_REG and verify no error bits are
|
|
// asserted, all read, write, and erase operations are
|
|
// idle, and write protection is disabled.{/li}
|
|
// {p}{li}Set the target address for the write to the Max 10
|
|
// on-chip flash by writing value from
|
|
// FLASH_CFM0_START_ADDR_REG to FLASH_ADDR_REG.{/li}{/p}
|
|
// {p}{li}Set the data to be written to this address by writing
|
|
// the new 32-bit word of the new image to
|
|
// FLASH_WRITE_DATA_REG.{/li}{/p}
|
|
// {p}{li}Initiate the write by strobing FLASH_WRITE_STB of
|
|
// FLASH_CONTROL_REG.{/li}{/p}
|
|
// {p}{li}Poll the FLASH_WRITE_IDLE bit of
|
|
// FLASH_STATUS_REG until it de-asserts indicating the
|
|
// write operation is complete, then verify the operation
|
|
// was successful by checking that the FLASH_WRITE_ERR
|
|
// bit is de-asserted. Write operations are expected to
|
|
// take a maximum of 550 usec.{/li}{/p}
|
|
// {p}{li}Upon completion of the write operation return to step
|
|
// 2, incrementing the target address by one, and writing
|
|
// the next 32-bit word to Max10FlashWriteDatReg. If this
|
|
// was the last write, indicated by writing to
|
|
// FLASH_PRIMARY_IMAGE_END_ADDR, proceed to the next step
|
|
// to enable write protection.{/li}{/p}
|
|
// {p}{li}After writing the new image enable write protection
|
|
// by strobing the FLASH_ENABLE_WP_STB bit of
|
|
// FLASH_CONTROL_REG.{/li}{/p}
|
|
// {/ol}
|
|
// {/p}
|
|
// {p}{b}Verify the new primary flash image...{/b}
|
|
// {ol}{p}{li}Read FLASH_STATUS_REG and verify no error bits are
|
|
// asserted and that all read, write, and erase operations
|
|
// are idle.{/li}{/p}
|
|
// {p}{li}Set the target address for the read in the Max 10
|
|
// on-chip flash by writing value from
|
|
// FLASH_CFM0_START_ADDR_REG to FLASH_ADDR_REG.{/li}{/p}
|
|
// {p}{li}Initiate the read by strobing FLASH_READ_STB of
|
|
// FLASH_CONTROL_REG.{/li}{/p}
|
|
// {p}{li}Poll the FLASH_READ_IDLE bit of
|
|
// FLASH_STATUS_REG until it de-asserts indicating the
|
|
// read operation is complete, then verify the operation
|
|
// was successful by checking that the FLASH_READ_ERR
|
|
// bit is de-asserted. There is no guidance on exactly how
|
|
// long reads take to complete, but they are expected to be
|
|
// fairly quick. A very conservative timeout on this
|
|
// polling would be similar to that used for write
|
|
// operations.{/li}{/p}
|
|
// {p}{li}Upon completion of the read operation the resulting
|
|
// data returned by the on-chip flash will be available in
|
|
// Max10FlashReadDatReg. Read this register, compare to
|
|
// expected value previously written, and ensure they
|
|
// match.{/li}{/p}
|
|
// {p}{li}Return to step 2, incrementing the target
|
|
// address by one. If this was the last read verification
|
|
// is complete and no further action is required.{/li}{/p}
|
|
// {/ol}
|
|
// {/p}
|
|
// {p}After the flash has been erased, programmed, and verified, a power
|
|
// cycle is required for the new image to become active.
|
|
// {/p}
|
|
// </info>
|
|
// <enumeratedtype name="FLASH_PRIMARY_IMAGE_ADDR_ENUM" showhexvalue="true">
|
|
// <info>
|
|
// These values are the start and end address of the CFM image flash
|
|
// sector from Intel's On-Chip Flash IP Generator.
|
|
// Be aware that three different values exist per each of the two
|
|
// supported MAX10 variants: 10M04 and 10M08
|
|
// Note that the values given in the IP generator are byte based where
|
|
// the values of this enum are U32 based (divided by 4).
|
|
// </info>
|
|
// <value name="FLASH_PRIMARY_IMAGE_START_ADDR_MEM_INIT_10M04"
|
|
// integer="4096"/>
|
|
// <value name="FLASH_PRIMARY_IMAGE_START_ADDR_10M04"
|
|
// integer="39936"/>
|
|
// <value name="FLASH_PRIMARY_IMAGE_END_ADDR_10M04"
|
|
// integer="75775"/>
|
|
//
|
|
// <value name="FLASH_PRIMARY_IMAGE_START_ADDR_MEM_INIT_10M08"
|
|
// integer="8192"/>
|
|
// <value name="FLASH_PRIMARY_IMAGE_START_ADDR_10M08"
|
|
// integer="44032"/>
|
|
// <value name="FLASH_PRIMARY_IMAGE_END_ADDR_10M08"
|
|
// integer="79871"/>
|
|
// </enumeratedtype>
|
|
// <register name="FLASH_STATUS_REG" offset="0x000" size="32"
|
|
// attributes="Readable">
|
|
// <bitfield name="FLASH_WP_ENABLED" range="0">
|
|
// <info>
|
|
// This bit is asserted when the flash is write protected and
|
|
// de-asserted when write protection is disabled.
|
|
// {li}Write protection must be enabled prior to performing read
|
|
// operations.{/li}
|
|
// {li}Write protection must be disabled prior to performing write and
|
|
// erase operations.{/li}
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="FLASH_READ_IDLE" range="4">
|
|
// <info>
|
|
// This bit is de-asserted when a read operation is in progress. Poll
|
|
// this bit after strobing the FLASH_READ_STB bit of
|
|
// FLASH_CONTROL_REG to determine when the read operation has
|
|
// completed, then check the FLASH_READ_ERR bit to verify the
|
|
// operation was successful.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="FLASH_READ_ERR" range="5">
|
|
// <info>
|
|
// This bit is asserted when a read operation fails. Clear this error
|
|
// by strobing the CLEAR_FLASH_READ_ERROR_STB of this register. In the
|
|
// event of a read error...
|
|
// {li}the data in FLASH_READ_DATA_REG is invalid.{/li}
|
|
// {li}attempts to disable write protection will be ignored.{/li}
|
|
// {li}attempts to read/write/erase the flash will be ignored.{/li}
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="FLASH_ERASE_IDLE" range="8">
|
|
// <info>
|
|
// This bit is de-asserted when an erase operation is in progress. Poll
|
|
// this bit after strobing the FLASH_ERASE_STB bit of
|
|
// FLASH_CONTROL_REG to determine when the erase operation has
|
|
// completed, then check the FLASH_ERASE_ERR bit to verify the
|
|
// operation was successful.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="FLASH_ERASE_ERR" range="9">
|
|
// <info>
|
|
// This bit is asserted when an erase operation fails. Clear this
|
|
// error by strobing CLEAR_FLASH_ERASE_ERROR_STB of this register. In
|
|
// the event of an erase error...
|
|
// {li}{b}the primary configuration image may be corrupted,{/b} and
|
|
// power cycling the board may result in unknown behavior.{/li}
|
|
// {li}write protection of the flash will automatically be
|
|
// re-enabled.{/li}
|
|
// {li}attempts to disable write protection will be ignored.{/li}
|
|
// {li}attempts to read/write/erase the flash will be ignored.{/li}
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="FLASH_WRITE_IDLE" range="12">
|
|
// <info>
|
|
// This bit is de-asserted when a write operation is in progress. Poll
|
|
// this bit after strobing the FLASH_WRITE_STB bit of
|
|
// FLASH_CONTROL_REG to determine when the write operation has
|
|
// completed, then check the FLASH_WRITE_ERR bit to verify the
|
|
// operation was successful.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="FLASH_WRITE_ERR" range="13">
|
|
// <info>
|
|
// This bit is asserted when write operation fails. Clear this error
|
|
// by strobing the CLEAR_FLASH_WRITE_ERROR_STB bit of this register. In
|
|
// the event of a write error...
|
|
// {li}{b}the primary configuration image may be corrupted,{/b} and
|
|
// power cycling the board may result unknown behavior.{/li}
|
|
// {li}write protection of the flash will automatically be
|
|
// re-enabled.{/li}
|
|
// {li}attempts to disable write protection will be ignored.{/li}
|
|
// {li}attempts to read/write/erase the flash will be ignored.{/li}
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="FLASH_MEM_INIT_ENABLED" range="16">
|
|
// <info>
|
|
// This bit is asserted when the flash can hold an image with memory
|
|
// initialization.
|
|
// </info>
|
|
// </bitfield>
|
|
// </register>
|
|
// <register name="FLASH_CONTROL_REG" offset="0x04" size="32"
|
|
// attributes="Writable">
|
|
// <bitfield name="FLASH_ENABLE_WP_STB" range="0"
|
|
// attributes="strobe">
|
|
// <info>
|
|
// Strobe this bit to enable write protection to the section of the
|
|
// Max 10 on-chip flash storing the primary configuration image
|
|
// (CFM0).
|
|
// {li}Read the FLASH_WP_ENABLED bit of FLASH_STATUS_REG to
|
|
// determine the current state of write protection.{/li}
|
|
// {li}Prior to strobing this bit verify no write or erase operations
|
|
// are in progress and no error bits are asserted by reading
|
|
// FLASH_STATUS_REG.{/li}
|
|
// {li}Attempts to enable write protection while erase or write
|
|
// operations are in progress will be ignored.{/li}
|
|
// {li}Write protection must be enabled prior to performing
|
|
// read operations.{/li}
|
|
// {li}Write protection should be enabled after completing
|
|
// write or erase operations to prevent data corruption.{/li}
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="FLASH_DISABLE_WP_STB" range="1"
|
|
// attributes="strobe">
|
|
// <info>
|
|
// Strobe this bit to disable write protection to the section of the
|
|
// Max 10 on-chip flash storing the primary configuration image
|
|
// (CFM0).
|
|
// {li}Read the FLASH_WP_ENABLED bit of FLASH_STATUS_REG to
|
|
// determine the current state of write protection.{/li}
|
|
// {li}Prior to strobing this bit verify no read operations are in
|
|
// progress and no error bits are asserted by reading
|
|
// FLASH_STATUS_REG.{/li}
|
|
// {li}Attempts to disable write protection while a read is in
|
|
// progress will be ignored.{/li}
|
|
// {li}Attempts to disable write protection will be ignored if
|
|
// this bit is strobed simultaneously with either FLASH_READ_STB
|
|
// or FLASH_ENABLE_WP_STB.{/li}
|
|
// {li}Write protection must be disabled prior to performing erase or
|
|
// write operations.{/li}
|
|
// {li}Upon completion of erase/write operations write protection
|
|
// will remain disabled. When not actively erasing or writing a new
|
|
// image write protection should be enabled to avoid data
|
|
// corruption.{/li}
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="FLASH_READ_STB" range="2"
|
|
// attributes="strobe">
|
|
// <info>
|
|
// Strobe this bit to read data from the flash address identified in
|
|
// FLASH_ADDR_REG.
|
|
// {li}Prior to strobing this bit verify no read, write, or erase
|
|
// operations are in progress, no error bits are asserted, and
|
|
// write protection is enabled by reading FLASH_STATUS_REG.{/li}
|
|
// {li}Attempts to read data while other operations are in progress
|
|
// or while write protection is disabled will be ignored.{/li}
|
|
// {li}After strobing this bit poll the FLASH_READ_IDLE and
|
|
// FLASH_READ_ERR bits of FLASH_STATUS_REG to determine when
|
|
// the read operation is complete and if it was successful.{/li}
|
|
// {li}Upon successful completion the data read from flash will be
|
|
// available in FLASH_READ_DATA_REG.{/li}
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="FLASH_WRITE_STB" range="3"
|
|
// attributes="strobe">
|
|
// <info>
|
|
// Strobe this bit to write the data contained in
|
|
// FLASH_WRITE_DATA_REG to the flash address identified in
|
|
// FLASH_ADDR_REG.
|
|
// {li}The flash must be erased before writing new data.{/li}
|
|
// {li}Prior to strobing this bit verify write protection is
|
|
// disabled, no other write or erase operations are in progress, and
|
|
// no error bits are asserted by reading FLASH_STATUS_REG.{/li}
|
|
// {li}Attempts to write data while other write or erase operations
|
|
// are in progress will be ignored.{/li}
|
|
// {li}Attempts to write data with write protection enabled will be
|
|
// ignored.{/li}
|
|
// {li}Strobing this bit and FLASH_ERASE_STB simultaneously will
|
|
// result in both the write and erase operation being ignored,
|
|
// both corresponding error bits being set, and write protection
|
|
// being re-enabled.{/li}
|
|
// {li}After strobing this bit poll theMax10FlashWriteIdle and
|
|
// FLASH_WRITE_ERR bits of FLASH_STATUS_REG to determine when
|
|
// the write operation is complete and if it was successful.{/li}
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="FLASH_ERASE_STB" range="4"
|
|
// attributes="strobe">
|
|
// <info>
|
|
// Strobe this bit to erase the primary Max10 configuration image
|
|
// (CFM0).
|
|
// {li}Prior to strobing this bit verify no other write or erase
|
|
// operations are in progress, write protection is disabled, and no
|
|
// error bits are asserted by reading FLASH_STATUS_REG.{/li}
|
|
// {li}Attempts to erase the primary image while other write or erase
|
|
// operations are in progress will be ignored.
|
|
// {li}Attempts to erase the primary image when write protection is
|
|
// enabled will be ignored.{/li}
|
|
// {li}Strobing this bit and FLASH_WRITE_STB simultaneously will
|
|
// result both the erase and the write operation being ignored, both
|
|
// corresponding error bits being set, and write protection being
|
|
// re-enabled.{/li}
|
|
// {li}After strobing this bit poll the FLASH_ERASE_IDLE and
|
|
// FLASH_ERASE_ERR bits of FLASH_STATUS_REG to determine when
|
|
// the erase operation is complete and if it was successful.{/li}
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="FLASH_ERASE_SECTOR" range="7..5"
|
|
// attributes="strobe">
|
|
// <info>
|
|
// Defines the sector to be erased. Has to be set latest with the
|
|
// write access which starts the erase operation by strobing
|
|
// @.FLASH_ERASE_STB.{br}
|
|
// With 10M04 variants, if the flash is configured to support memory
|
|
// initialization (see @.FLASH_MEM_INIT_ENABLED flag) the sectors 2
|
|
// to 4 have to be erased. If the flag is not asserted only sector 4
|
|
// has to be erased.
|
|
// With 10M08 variants, the sectors to be erased are 3 to 5 when
|
|
// using memory initialization or only sector 5 otherwise.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="CLEAR_FLASH_READ_ERROR_STB" range="8"
|
|
// attributes="strobe">
|
|
// <info>
|
|
// Strobe this bit to clear a read error.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="CLEAR_FLASH_WRITE_ERROR_STB" range="9"
|
|
// attributes="strobe">
|
|
// <info>
|
|
// Strobe this bit to clear a write error.
|
|
// </info>
|
|
// </bitfield>
|
|
// <bitfield name="CLEAR_FLASH_ERASE_ERROR_STB" range="10"
|
|
// attributes="strobe">
|
|
// <info>
|
|
// Strobe this bit to clear an erase error.
|
|
// </info>
|
|
// </bitfield>
|
|
// </register>
|
|
// <register name="FLASH_ADDR_REG" offset="0x08" size="32"
|
|
// attributes="Readable|Writable">
|
|
// <bitfield name="FLASH_ADDR" range="16..0">
|
|
// <info>
|
|
// This field holds the target address for the next read or
|
|
// write operation. Set this field prior to strobing the
|
|
// FLASH_WRITE_STB and FLASH_READ_STB bits of
|
|
// FLASH_CONTROL_REG. Valid addresses are defined by the
|
|
// FLASH_PRIMARY_IMAGE_ADDR_ENUM enumeration.
|
|
// </info>
|
|
// </bitfield>
|
|
// </register>
|
|
// <register name="FLASH_WRITE_DATA_REG" offset="0x0C" size="32"
|
|
// attributes="Writable">
|
|
// <bitfield name="FLASH_WRITE_DATA" range="31..0">
|
|
// <info>
|
|
// Data in this register will be written to the flash at the address
|
|
// identified in FLASH_ADDR_REG when a successful write operation
|
|
// is executed.
|
|
// </info>
|
|
// </bitfield>
|
|
// </register>
|
|
// <register name="FLASH_READ_DATA_REG" offset="0x10" size="32"
|
|
// attributes="Readable">
|
|
// <bitfield name="FLASH_READ_DATA" range="31..0">
|
|
// <info>
|
|
// This register contains data read from the flash address identified
|
|
// in FLASH_ADDR_REG after a successful read operation is executed.
|
|
// </info>
|
|
// </bitfield>
|
|
// </register>
|
|
// <register name="FLASH_CFM0_START_ADDR_REG" offset="0x14" size="32"
|
|
// attributes="Readable">
|
|
// <bitfield name="FLASH_CFM0_START_ADDR" range="31..0">
|
|
// <info>
|
|
// Start address of CFM0 image within flash memory (as defined in FLASH_PRIMARY_IMAGE_ADDR_ENUM).
|
|
// </info>
|
|
// </bitfield>
|
|
// </register>
|
|
// <register name="FLASH_CFM0_END_ADDR_REG" offset="0x18" size="32"
|
|
// attributes="Readable">
|
|
// <bitfield name="FLASH_CFM0_END_ADDR" range="31..0">
|
|
// <info>
|
|
// Last address of CFM0 image within flash memory (as defined in FLASH_PRIMARY_IMAGE_ADDR_ENUM).
|
|
// </info>
|
|
// </bitfield>
|
|
// </register>
|
|
// </group>
|
|
//</regmap>
|
|
//XmlParse xml_off
|