`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 21:57:50 08/25/2009 // Design Name: // Module Name: mcu_cmd // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module mcu_cmd( input clk, input cmd_ready, input param_ready, input [7:0] cmd_data, input [7:0] param_data, output mcu_rrq, output mcu_wrq, input mcu_rq_rdy, output [7:0] mcu_data_out, input [7:0] mcu_data_in, output [7:0] spi_data_out, input [31:0] spi_byte_cnt, input [2:0] spi_bit_cnt, output [23:0] addr_out, output [23:0] saveram_mask_out, output [23:0] rom_mask_out ); reg [7:0] MCU_DATA_OUT_BUF; reg [7:0] MCU_DATA_IN_BUF; reg [2:0] mcu_nextaddr_buf; wire mcu_nextaddr; reg [23:0] SAVERAM_MASK; reg [23:0] ROM_MASK; reg [23:0] ADDR_OUT_BUF; assign spi_data_out = MCU_DATA_IN_BUF; initial begin ADDR_OUT_BUF = 0; end // command interpretation always @(posedge clk) begin if (param_ready) begin casex (cmd_data[7:0]) 8'h1x: case (spi_byte_cnt) 32'h2: ROM_MASK[23:16] <= param_data; 32'h3: ROM_MASK[15:8] <= param_data; 32'h4: ROM_MASK[7:0] <= param_data; endcase 8'h2x: case (spi_byte_cnt) 32'h2: SAVERAM_MASK[23:16] <= param_data; 32'h3: SAVERAM_MASK[15:8] <= param_data; 32'h4: SAVERAM_MASK[7:0] <= param_data; endcase 8'h9x: MCU_DATA_OUT_BUF <= param_data; endcase end end always @(posedge clk) begin if(param_ready && cmd_data[7:4] == 4'h0) begin case (spi_byte_cnt) 32'h2: begin ADDR_OUT_BUF[23:16] <= param_data; ADDR_OUT_BUF[15:0] <= 16'b0; end 32'h3: ADDR_OUT_BUF[15:8] <= param_data; 32'h4: ADDR_OUT_BUF[7:0] <= param_data; endcase end else if ((mcu_nextaddr & (cmd_data[7:5] == 3'h4) && (cmd_data[3]) && (spi_byte_cnt >= (32'h1+cmd_data[4]))) ) begin ADDR_OUT_BUF <= ADDR_OUT_BUF + 1; end end // value fetch during last SPI bit always @(posedge clk) begin if (cmd_data[7:4] == 4'h8 && mcu_nextaddr) MCU_DATA_IN_BUF <= mcu_data_in; else if (cmd_ready | param_ready /* bit_cnt == 7 */) begin if (cmd_data[7:0] == 8'hF0) MCU_DATA_IN_BUF <= 8'hA5; else if (cmd_data[7:0] == 8'hFF) MCU_DATA_IN_BUF <= param_data; end end // nextaddr pulse generation always @(posedge clk) begin mcu_nextaddr_buf <= {mcu_nextaddr_buf[1:0], mcu_rq_rdy}; end parameter ST_RQ = 2'b01; parameter ST_IDLE = 2'b10; reg [1:0] rrq_state; initial rrq_state = ST_IDLE; reg mcu_rrq_r; reg [1:0] wrq_state; initial wrq_state = ST_IDLE; reg mcu_wrq_r; always @(posedge clk) begin case(rrq_state) ST_IDLE: begin if((param_ready | cmd_ready) && cmd_data[7:4] == 4'h8) begin mcu_rrq_r <= 1'b1; rrq_state <= ST_RQ; end else rrq_state <= ST_IDLE; end ST_RQ: begin mcu_rrq_r <= 1'b0; rrq_state <= ST_IDLE; end endcase end always @(posedge clk) begin case(wrq_state) ST_IDLE: begin if(param_ready && cmd_data[7:4] == 4'h9) begin mcu_wrq_r <= 1'b1; wrq_state <= ST_RQ; end else wrq_state <= ST_IDLE; end ST_RQ: begin mcu_wrq_r <= 1'b0; wrq_state <= ST_IDLE; end endcase end // trigger for nextaddr assign mcu_nextaddr = mcu_nextaddr_buf == 2'b01; assign mcu_rrq = mcu_rrq_r; assign mcu_wrq = mcu_wrq_r; assign addr_out = ADDR_OUT_BUF; assign mcu_data_out = MCU_DATA_OUT_BUF; assign rom_mask_out = ROM_MASK; assign saveram_mask_out = SAVERAM_MASK; assign DBG_mcu_nextaddr = mcu_nextaddr; endmodule