| // | |
| // 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 |