blob: 4aa111156d4b9ada6f9142f65bdfea9d82e77c69 [file] [log] [blame]
// SPDX-FileCopyrightText: 2020 Efabless Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0
`default_nettype none
/*
*-------------------------------------------------------------
*
* system_controller
*
*
*-------------------------------------------------------------
*/
module system_controller
(
`ifdef USE_POWER_PINS
inout vccd1, // User area 1 1.8V supply
inout vssd1, // User area 1 digital ground
`endif
input wire clock,
input wire enable_sn,
input wire update_done,
input wire [31:0] spi_data,
input wire [31:0] ccr2,
input wire [31:0] ccr3,
input wire [15:0] memory_data_in,
output wire [15:0] memory_data_out,
output wire [15:0] memory_data,
output wire memory_enable_n,
output wire memory_write_n,
output wire memory_read_n,
output wire [7:0] memory_address,
output wire system_enable_n,
//output wire data_ready_n,
output wire data_valid_n,
output wire trigger_out_n,
input wire trigger_in_sn,
input wire latch_data_sn,
output wire [7:0] control_state
);
reg [1:0] mem_state;
reg [1:0] system_state;
reg [1:0] trigger_out_state;
reg [1:0] latch_data_state;
wire refresh_n;
reg [31:0] refresh_count;
reg [2:0] mem_read_state;
reg [15:0] memory_data_reg;
reg [31:0] system_data;
wire system_control_n;
always@(posedge clock)
begin
case({enable_sn,latch_data_state})
3'b0_00: latch_data_state <= latch_data_sn ? 2'b00 : 2'b01;
3'b0_01: latch_data_state <= 2'b10;
3'b0_10: latch_data_state <= 2'b11;
3'b0_11: latch_data_state <= latch_data_sn ? 2'b00 : 2'b11;
default latch_data_state <= 2'b00;
endcase
end
assign system_control_n = latch_data_state != 2'b10;
always@(posedge clock)
begin
case({enable_sn,latch_data_state})
3'b0_00: system_data <= system_data;
3'b0_01: system_data <= spi_data;
3'b0_10: system_data <= system_data;
3'b0_11: system_data <= system_data;
default: system_data <= 32'b0;
endcase
end
assign control_state = system_data[31:24];
assign memory_address = system_data[23:16];
assign memory_data_out = system_data[15:0];
always@(posedge clock)
begin
case({enable_sn,~system_control_n,control_state[1:0],mem_state})
6'b00_10_00: mem_state <= 2'b10;
6'b00_10_10: mem_state <= 2'b11;
6'b00_10_11: mem_state <= 2'b11;
6'b00_01_00: mem_state <= 2'b01;
6'b00_01_01: mem_state <= 2'b11;
6'b00_01_11: mem_state <= 2'b11;
default: mem_state <= 2'b00;
endcase
end
assign memory_enable_n = (^mem_state) ? 1'b0 : 1'b1;
assign memory_write_n = mem_state == 2'b10 ? 1'b0 : 1'b1;
assign memory_read_n = mem_state == 2'b01 ? 1'b0 : 1'b1;
always@(posedge clock)
begin
case({enable_sn,mem_read_state})
5'b0_000: mem_read_state <= memory_read_n ? 3'b000 : 3'b001;
5'b0_001: mem_read_state <= 3'b010;
5'b0_010: mem_read_state <= 3'b011;
5'b0_011: mem_read_state <= 3'b000;
//5'b0_100: mem_read_state <= 3'b000;
default : mem_read_state <= 3'b000;
endcase
end
assign data_valid_n = (mem_read_state == 3'b011) ? 1'b0 : 1'b1;
always@(posedge clock)
begin
case({enable_sn,mem_read_state})
4'b0_001: memory_data_reg <= memory_data_in;
default: memory_data_reg <= memory_data_reg;
endcase
end
assign memory_data = memory_data_reg;
//assign data_ready_n = mem_read_state[1] ? 1'b0 : 1'b1;
always@(posedge clock)
begin
case({enable_sn,~system_control_n,control_state[3:2],system_state})
6'b00_10_00: system_state <= trigger_in_sn ? 2'b00 : 2'b10;
6'b00_10_10: system_state <= update_done ? 2'b11 : 2'b10;
6'b00_10_11: system_state <= trigger_in_sn ? 2'b00 : 2'b11;
6'b00_01_00: system_state <= 2'b10;
6'b00_01_10: system_state <= update_done ? 2'b11 : 2'b10;
6'b00_01_11: system_state <= refresh_n ? 2'b11 : 2'b10;
default: system_state <= 2'b00;
endcase
end
assign system_enable_n = ~^system_state;
always@(posedge clock)
begin
case({enable_sn,trigger_out_state})
3'b0_00: trigger_out_state <= update_done ? 2'b01 : 2'b00;
3'b0_01: trigger_out_state <= 2'b10;
3'b0_10: trigger_out_state <= 2'b11;
default: trigger_out_state <= 2'b00;
endcase
end
assign trigger_out_n = ~^trigger_out_state;
always@(posedge clock)
begin
if(enable_sn | system_control_n)
begin
refresh_count <= 32'b0;
end
else
begin
if((control_state[2]) & (&system_state))
begin
if(refresh_count <= ccr3)
begin
refresh_count <= refresh_count+1'b1;
end
else
begin
refresh_count <= 32'b0;
end
end
else
begin
refresh_count <= 32'b0;
end
end
end
assign refresh_n = (refresh_count != ccr2);
endmodule