blob: ce495ed7c861e846f5ce4ae37c09665d9fcdde1f [file] [log] [blame]
// Copyright 2025 Google LLC
//
// 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.
module chip_verilator
#(parameter MemInitFile = "",
parameter int ClockFrequencyMhz = 80)
(input clk_i,
input rst_ni,
input spi_clk_i,
input prim_mubi_pkg::mubi4_t scanmode_i,
input top_pkg::uart_sideband_i_t[1 : 0] uart_sideband_i,
output top_pkg::uart_sideband_o_t[1 : 0] uart_sideband_o);
logic uart0_rx;
logic uart0_tx;
uartdpi #(.BAUD(115200),
.FREQ(ClockFrequencyMhz * 1_000_000),
.NAME("uart0"),
.EXIT_STRING("EXIT"))
i_uartdpi0(.clk_i(clk_i),
.rst_ni(rst_ni),
.active(1'b1),
.tx_o(uart0_rx),
.rx_i(uart0_tx));
logic uart1_rx;
logic uart1_tx;
uartdpi #(.BAUD(115200),
.FREQ(ClockFrequencyMhz * 1_000_000),
.NAME("uart1"),
.EXIT_STRING("EXIT"))
i_uartdpi1(.clk_i(clk_i),
.rst_ni(rst_ni),
.active(1'b1),
.tx_o(uart1_rx),
.rx_i(uart1_tx));
kelvin_soc #(.MemInitFile(MemInitFile),
.ClockFrequencyMhz(ClockFrequencyMhz))
i_kelvin_soc(.clk_i(clk_i),
.rst_ni(rst_ni),
.ibex_clk_i(ibex_clk_i),
.ibex_rst_ni(ibex_rst_ni),
.spi_clk_i(spi_clk_i),
.scanmode_i(scanmode_i),
.uart_sideband_i(
'{'{cio_rx: uart0_rx}, '{cio_rx: uart1_rx}}),
.uart_sideband_o(uart_sideband_o),
.io_halted(),
.io_fault());
assign uart0_tx = uart_sideband_o[0].cio_tx;
assign uart1_tx = uart_sideband_o[1].cio_tx;
// Clock divider for Ibex clock.
logic [1:0] clk_divider;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
clk_divider <= 2'b0;
end else begin
clk_divider <= clk_divider + 1;
end
end
logic ibex_clk_i;
assign ibex_clk_i = clk_divider[1];
// Reset synchronizer for Ibex reset.
logic ibex_rst_ni;
logic rst_n_sync;
always_ff @(posedge ibex_clk_i or negedge rst_ni) begin
if (!rst_ni) begin
rst_n_sync <= 1'b0;
ibex_rst_ni <= 1'b0;
end else begin
rst_n_sync <= 1'b1;
ibex_rst_ni <= rst_n_sync;
end
end
endmodule