blob: 826782f983409bcefadf5b7de9ab5ed78a026e97 [file] [log] [blame]
//
// Copyright 2022 Tobias Strauch, Munich, Bavaria
//
// 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
//
// Design includes
// Whishbone logic and
// Calendar design
//
module cawb (
`ifdef USE_POWER_PINS
inout vccd1, // User area 1 1.8V supply
inout vssd1, // User area 1 digital ground
`endif
input wb_clk_i,
input wb_rst_i,
input wbs_stb_i,
input wbs_cyc_i,
input wbs_we_i,
input [3:0] wbs_sel_i,
input [31:0] wbs_dat_i,
input [31:0] wbs_adr_i,
output wbs_ack_o,
output [31:0] wbs_dat_o,
input [127:0] la_data_in,
output [127:0] la_data_out,
input [127:0] la_oenb,
output [2:0] irq,
output rstn_reg,
output cubev_pli_clk0,
output cubev_pli_csb0,
output cubev_pli_web0,
output [3:0] cubev_pli_wmask0,
output [7:0] cubev_pli_addr0,
output [31:0] cubev_pli_din0,
input [31:0] cubev_pli_dout0,
output cubev_phi_clk0,
output cubev_phi_csb0,
output cubev_phi_web0,
output [3:0] cubev_phi_wmask0,
output [7:0] cubev_phi_addr0,
output [31:0] cubev_phi_din0,
input [31:0] cubev_phi_dout0,
input ca_dbus_valid,
output ca_dbus_ack,
input ca_dbus_com,
input [2:0] ca_dbus_tid,
input [31:0] ca_dbus_data,
output ca_time_valid,
input ca_time_ack,
output [22:0] ca_time_data,
output ca_match_valid,
input ca_match_ack,
output [31:0] ca_command,
output cubev_ca_clk0,
output cubev_ca_csb0,
output cubev_ca_web0,
output [3:0] cubev_ca_wmask0,
output [7:0] cubev_ca_addr0,
output [31:0] cubev_ca_din0,
input [31:0] cubev_ca_dout0,
output cubev_ca_clk1,
output cubev_ca_csb1,
output [7:0] cubev_ca_addr1,
input [31:0] cubev_ca_dout1);
assign cubev_ca_clk0 = wb_clk_i;
assign cubev_ca_csb0 = 1'b0;
assign cubev_ca_wmask0 = 4'hf;
assign cubev_ca_clk1 = wb_clk_i;
assign cubev_ca_csb1 = 1'b0;
assign cubev_pli_clk0 = wb_clk_i;
assign cubev_pli_csb0 = 1'b0;
assign cubev_pli_wmask0 = 4'hf;
assign cubev_pli_addr0 = prog_addra[8:1];
assign cubev_pli_din0 = prog_dina;
assign cubev_phi_clk0 = wb_clk_i;
assign cubev_phi_csb0 = 1'b0;
assign cubev_phi_wmask0 = 4'hf;
assign cubev_phi_addr0 = prog_addra[8:1];
assign cubev_phi_din0 = prog_dina;
///////////////////////////////////////////////////
// Program prog_l and ptog_h memory
///////////////////////////////////////////////////
reg prog_wea;
reg [10:0] prog_addra;
reg [31:0] prog_dina;
reg wbs_ack_o;
reg wbs_ack_int;
reg rstn_reg;
assign wbs_dat_o = cubev_pli_dout0 ^ cubev_phi_dout0;
assign irq = 0;
reg [127:0] la_data_out;
always @(negedge wb_clk_i) begin
la_data_out[ 31: 0] <= cubev_pli_dout0;
la_data_out[ 63:32] <= cubev_phi_dout0;
//la_data_out[ 71:64] <= cubev_pli_pcl[11:3];
//la_data_out[ 79:72] <= cubev_phi_pch[11:3];
la_data_out[ 95] <= ca_match_valid;
la_data_out[127:96] <= ca_command;
end
assign cubev_phi_web0 = ~(prog_wea & prog_addra[0]);
assign cubev_pli_web0 = ~(prog_wea & !prog_addra[0]);
always @(negedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i) begin
prog_wea <= 0;
prog_addra <= 0;
prog_dina <= 0;
wbs_ack_o <= 0;
rstn_reg <= 0;
end else begin
prog_wea <= 0;
wbs_ack_o <= wbs_ack_int & !wbs_ack_o;
wbs_ack_int <= 0;
if (la_data_in[64]) begin
prog_wea <= 1'b1;
prog_addra <= la_data_in[42:32];
prog_dina <= la_data_in[31:0];
end else
if (la_data_in[65]) begin
rstn_reg <= 1'b1;
end else
if (wbs_cyc_i && wbs_stb_i) begin
if (wbs_adr_i[31:16] == 16'h3000) begin
if (wbs_we_i) begin
prog_wea <= ~wbs_ack_int;
prog_addra <= wbs_adr_i[12:2];
prog_dina <= wbs_dat_i;
end
if (wbs_adr_i[11:0] == 12'h7FC)
rstn_reg <= 1'b1;
end
end
end
assign prog_h_addr0 = prog_addra;
assign prog_l_addr0 = prog_addra;
assign prog_h_din = prog_dina;
assign prog_l_din = prog_dina;
///////////////////////////////////////////////////
// Negative edge registers to overcome potential
// hold time violations for the external Calendar
// memory.
///////////////////////////////////////////////////
reg cubev_ca_web0;
reg [7:0] cubev_ca_addr0;
reg [31:0] cubev_ca_din0;
reg [7:0] cubev_ca_addr1;
wire cubev_ca_wea_int;
wire [8:0] cubev_ca_addra_int;
wire [31:0] cubev_ca_dina_int;
wire [8:0] cubev_ca_addrb_int;
always @(negedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i) begin
cubev_ca_web0 <= 0;
cubev_ca_addr0 <= 0;
cubev_ca_din0 <= 0;
cubev_ca_addr1 <= 0;
end else begin
cubev_ca_web0 <= cubev_ca_wea_int;
cubev_ca_addr0 <= cubev_ca_addra_int[7:0];
cubev_ca_din0 <= cubev_ca_dina_int;
cubev_ca_addr1 <= cubev_ca_addrb_int[7:0];
end
///////////////////////////////////////////////////
// Instantiation of the Calendar design
///////////////////////////////////////////////////
ca i_ca (.clk_const(wb_clk_i),
.rstn(rstn_reg),
.test_overflow(1'b0),
.ca_dbus_valid(ca_dbus_valid),
.ca_dbus_ack(ca_dbus_ack),
.ca_dbus_com(ca_dbus_com),
.ca_dbus_tid(ca_dbus_tid),
.ca_dbus_data(ca_dbus_data),
.ca_time_valid(ca_time_valid),
.ca_time_ack(ca_time_ack),
.ca_time_data(ca_time_data),
.ca_match_valid(ca_match_valid),
.ca_match_ack(ca_match_ack),
.ca_command(ca_command),
.cubev_ca_wea(cubev_ca_wea_int),
.cubev_ca_addra(cubev_ca_addra_int),
.cubev_ca_dina(cubev_ca_dina_int),
.cubev_ca_douta(cubev_ca_dout0),
.cubev_ca_addrb(cubev_ca_addrb_int),
.cubev_ca_doutb(cubev_ca_dout1));
endmodule