mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
uncore: Add bsg_dmc and expose DDR PHY interface
This commit is contained in:
parent
7aef43372d
commit
b05893647f
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -29,3 +29,6 @@
|
||||
[submodule "addins/ahbsdc"]
|
||||
path = addins/ahbsdc
|
||||
url = http://github.com/JacobPease/ahbsdc.git
|
||||
[submodule "src/uncore/basejump_stl"]
|
||||
path = src/uncore/basejump_stl
|
||||
url = https://github.com/bespoke-silicon-group/basejump_stl
|
||||
|
114
src/uncore/ahbxuiconverter.sv
Normal file
114
src/uncore/ahbxuiconverter.sv
Normal file
@ -0,0 +1,114 @@
|
||||
///////////////////////////////////////////
|
||||
// ahbxuiconverter.sv
|
||||
//
|
||||
// Written: infinitymdm@gmail.com
|
||||
//
|
||||
// Purpose: AHB to Xilinx UI converter
|
||||
//
|
||||
// Documentation:
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
// https://github.com/openhwgroup/cvw
|
||||
//
|
||||
// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work 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 ahbxuiconverter #(parameter ADDR_SIZE = 31,
|
||||
parameter DATA_SIZE = 64) (
|
||||
// AHB signals
|
||||
input logic HCLK,
|
||||
input logic HRESETn,
|
||||
input logic HSEL,
|
||||
input logic [ADDR_SIZE-1:0] HADDR,
|
||||
input logic [DATA_SIZE-1:0] HWDATA,
|
||||
input logic [DATA_SIZE/8-1:0] HWSTRB,
|
||||
input logic HWRITE,
|
||||
input logic [1:0] HTRANS,
|
||||
input logic HREADY,
|
||||
output logic [DATA_SIZE-1:0] HRDATA,
|
||||
output logic HRESP,
|
||||
output logic HREADYOUT,
|
||||
|
||||
// UI signals
|
||||
output logic sys_reset,
|
||||
input logic ui_clk, // from PLL
|
||||
input logic ui_clk_sync_rst,
|
||||
output logic [ADDR_SIZE-1:0] app_addr, // Double check this width
|
||||
output logic [2:0] app_cmd,
|
||||
output logic app_en,
|
||||
input logic app_rdy,
|
||||
output logic app_wdf_wren,
|
||||
output logic [DATA_SIZE-1:0] app_wdf_data,
|
||||
output logic [DATA_SIZE/8-1:0] app_wdf_mask,
|
||||
output logic app_wdf_end,
|
||||
input logic app_wdf_rdy,
|
||||
input logic [DATA_SIZE-1:0] app_rd_data,
|
||||
input logic app_rd_data_end,
|
||||
input logic app_rd_data_valid,
|
||||
input logic init_calib_complete
|
||||
);
|
||||
|
||||
assign sys_reset = ~HRESETn;
|
||||
|
||||
// Enable this peripheral when:
|
||||
// a) selected, AND
|
||||
// b) a transfer is started, AND
|
||||
// c) the bus is ready
|
||||
logic ahbEnable;
|
||||
assign ahbEnable = HSEL & HTRANS[1] & HREADY;
|
||||
|
||||
// UI is ready for a command when initialized and ready to read and write
|
||||
logic uiReady;
|
||||
assign uiReady = app_rdy & app_wdf_rdy & init_calib_complete;
|
||||
|
||||
// Buffer the input down to ui_clk speed
|
||||
logic [ADDR_SIZE-1:0] addr;
|
||||
logic [DATA_SIZE-1:0] data;
|
||||
logic [DATA_SIZE/8-1:0] mask;
|
||||
logic cmdEnable, cmdWrite;
|
||||
logic cmdwfull, cmdrempty;
|
||||
// FIFO needs addr + (data + mask) + (enable + write)
|
||||
fifo #(ADDR_SIZE + 9*DATA_SIZE/8 + 2, 32) cmdfifo (
|
||||
.wdata({HADDR, HWDATA, HWSTRB, ahbEnable, HWRITE}),
|
||||
.winc(ahbEnable), .wclk(HCLK), .wrst_n(HRESETn),
|
||||
.rinc(uiReady), .rclk(ui_clk), .rrst_n(~ui_clk_sync_rst),
|
||||
.rdata({addr, data, mask, cmdEnable, cmdWrite}),
|
||||
.wfull(cmdwfull), .rempty(cmdrempty)
|
||||
);
|
||||
|
||||
// Delay transactions 1 clk so we can set wren on the cycle after write commands
|
||||
flopen #(ADDR_SIZE) addrreg (ui_clk, uiReady, addr, app_addr);
|
||||
flopenr #(3) cmdreg (ui_clk, ui_clk_sync_rst, uiReady, {2'b0, ~cmdWrite}, app_cmd);
|
||||
flopenr #(1) cmdenreg (ui_clk, ui_clk_sync_rst, uiReady, cmdEnable, app_en);
|
||||
flopenr #(1) wrenreg (ui_clk, ui_clk_sync_rst, uiReady, ~app_cmd[0], app_wdf_wren);
|
||||
flopenr #(DATA_SIZE) datareg (ui_clk, ui_clk_sync_rst, uiReady, data, app_wdf_data);
|
||||
flopenr #(DATA_SIZE/8) maskreg (ui_clk, ui_clk_sync_rst, uiReady, mask, app_wdf_mask);
|
||||
assign app_wdf_end = app_wdf_wren; // Since AHB will always put data on the bus after a write cmd, this is always valid
|
||||
|
||||
// Return read data at HCLK speed TODO: Double check that rinc is correct
|
||||
logic respwfull, resprempty;
|
||||
fifo #(DATA_SIZE, 16) respfifo (
|
||||
.wdata(app_rd_data),
|
||||
.winc(app_rd_data_valid), .wclk(ui_clk), .wrst_n(~ui_clk_sync_rst),
|
||||
.rinc(ahbEnable), .rclk(HCLK), .rrst_n(HRESETn),
|
||||
.rdata(HRDATA),
|
||||
.wfull(respwfull), .rempty(resprempty)
|
||||
);
|
||||
|
||||
assign HRESP = 0; // do not indicate errors
|
||||
assign HREADYOUT = uiReady & ~cmdwfull; // TODO: Double check
|
||||
|
||||
endmodule
|
1
src/uncore/basejump_stl
Submodule
1
src/uncore/basejump_stl
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 14f29e4d8a498ad62ec05fe232407f9d887e36a9
|
164
src/uncore/bsg_dmc_ahb.sv
Normal file
164
src/uncore/bsg_dmc_ahb.sv
Normal file
@ -0,0 +1,164 @@
|
||||
///////////////////////////////////////////
|
||||
// bsg_dmc_ahb.sv
|
||||
//
|
||||
// Written: infinitymdm@gmail.com
|
||||
//
|
||||
// Purpose: BSG controller and LPDDRDRAM presenting an AHB interface
|
||||
//
|
||||
// Documentation:
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
// https://github.com/openhwgroup/cvw
|
||||
//
|
||||
// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work 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.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "bsg_dmc.svh"
|
||||
|
||||
module bsg_dmc_ahb
|
||||
import bsg_tag_pkg::*;
|
||||
import bsg_dmc_pkg::*;
|
||||
#(
|
||||
parameter ADDR_SIZE = 28,
|
||||
parameter DATA_SIZE = 64,
|
||||
parameter BURST_LENGTH = 8,
|
||||
parameter FIFO_DEPTH = 4,
|
||||
) (
|
||||
input logic HCLK, HRESETn,
|
||||
input logic HSEL,
|
||||
input logic [ADDR_SIZE-1:0] HADDR,
|
||||
input logic [DATA_SIZE-1:0] HWDATA,
|
||||
input logic [DATA_SIZE/8-1:0] HWSTRB,
|
||||
input logic HWRITE,
|
||||
input logic [1:0] HTRANS,
|
||||
input logic HREADY,
|
||||
output logic [DATA_SIZE-1:0] HRDATA,
|
||||
output logic HRESP, HREADYOUT,
|
||||
//input logic ui_clk // Add this once PLL is integrated
|
||||
output logic ddr_ck_p, ddr_ck_n, ddr_cke,
|
||||
output logic [2:0] ddr_ba,
|
||||
output logic [15:0] ddr_addr,
|
||||
output logic ddr_cs, ddr_ras, ddr_cas,
|
||||
output logic ddr_we, ddr_reset, ddr_odt,
|
||||
output logic [DATA_SIZE/16-1:0] ddr_dm_oen, ddr_dm,
|
||||
output logic [DATA_SIZE/16-1:0] ddr_dqs_p_oen, ddr_dqs_p_ien, ddr_dqs_p_out,
|
||||
input logic [DATA_SIZE/16-1:0] ddr_dqs_p_in,
|
||||
output logic [DATA_SIZE/16-1:0] ddr_dqs_n_oen, ddr_dqs_n_ien, ddr_dqs_n_out,
|
||||
input logic [DATA_SIZE/16-1:0] ddr_dqs_n_in,
|
||||
output logic [DATA_SIZE/2-1:0] ddr_dq_oen, ddr_dq_out,
|
||||
input logic [DATA_SIZE/2-1:0] ddr_dq_in,
|
||||
input logic dfi_clk_2x,
|
||||
output logic dfi_clk_1x
|
||||
);
|
||||
|
||||
localparam BURST_DATA_SIZE = DATA_SIZE * BURST_LENGTH;
|
||||
// localparam DQ_DATA_SIZE = DATA_SIZE >> 1;
|
||||
|
||||
// Global async reset
|
||||
logic sys_reset;
|
||||
|
||||
// Memory controller config
|
||||
bsg_tag_s dmc_rst_tag, dmc_ds_tag;
|
||||
bsg_tag_s [3:0] dmc_dly_tag, dmc_dly_trigger_tag;
|
||||
bsg_dmc_s dmc_config;
|
||||
|
||||
// UI signals
|
||||
logic ui_clk_sync_rst;
|
||||
logic [ADDR_SIZE-1:0] app_addr;
|
||||
logic [2:0] app_cmd;
|
||||
logic app_en, app_rdy, app_wdf_wren;
|
||||
logic [DATA_SIZE-1:0] app_wdf_data;
|
||||
logic [DATA_SIZE/8-1:0] app_wdf_mask;
|
||||
logic app_wdf_end, app_wdf_rdy;
|
||||
logic [DATA_SIZE-1:0] app_rd_data;
|
||||
logic app_rd_data_end, app_rd_data_valid;
|
||||
logic app_ref_ack, app_zq_ack, app_sr_active; // Sink unused UI signals
|
||||
logic init_calib_complete;
|
||||
logic [11:0] device_temp; // Reserved
|
||||
|
||||
// Use a /6 clock divider until PLL is integrated. TODO: Replace
|
||||
logic ui_clk;
|
||||
integer clk_counter = 0;
|
||||
always @(posedge HCLK) begin
|
||||
counter <= counter + 1;
|
||||
if (counter >= 6) counter <= 0;
|
||||
ui_clk <= (counter >= 3);
|
||||
end
|
||||
|
||||
// TODO: Figure out how to initialize dmc_config correctly
|
||||
always_comb begin: bsg_dmc_config
|
||||
dmc_p.trefi = 1023;
|
||||
dmc_p.tmrd = 1;
|
||||
dmc_p.trfc = 15;
|
||||
dmc_p.trc = 10;
|
||||
dmc_p.trp = 2;
|
||||
dmc_p.tras = 7;
|
||||
dmc_p.trrd = 1;
|
||||
dmc_p.trcd = 2;
|
||||
dmc_p.twr = 10;
|
||||
dmc_p.twtr = 7;
|
||||
dmc_p.trtp = 10;
|
||||
dmc_p.tcas = 3;
|
||||
dmc_p.col_width = 11;
|
||||
dmc_p.row_width = 14;
|
||||
dmc_p.bank_width = 2;
|
||||
dmc_p.dqs_sel_cal = 3;
|
||||
dmc_p.init_cycles = 40010;
|
||||
dmc_p.bank_pos = 25;
|
||||
end
|
||||
|
||||
ahbxuiconverter #(ADDR_SIZE, DATA_SIZE) bsg_dmc_ahb_ui_converter (
|
||||
.HCLK, .HRESETn, .HSEL, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HTRANS, .HREADY, .HRDATA, .HRESP, .HREADYOUT,
|
||||
.sys_reset, .ui_clk, .ui_clk_sync_rst,
|
||||
.app_addr, .app_cmd, .app_en, .app_rdy,
|
||||
.app_wdf_wren, .app_wdf_data, .app_wdf_mask, .app_wdf_end, .app_wdf_rdy,
|
||||
.app_rd_data, .app_rd_data_end, .app_rd_data_valid,
|
||||
.init_calib_complete
|
||||
);
|
||||
|
||||
bsg_dmc #(
|
||||
.num_adgs_p(1),
|
||||
.ui_addr_width_p(ADDR_SIZE),
|
||||
.ui_data_width_p(DATA_SIZE),
|
||||
.burst_data_width_p(BURST_DATA_SIZE),
|
||||
.dq_data_width_p(DQ_DATA_SIZE),
|
||||
.cmd_afifo_depth(FIFO_DEPTH),
|
||||
.cmd_sfifo_depth(FIFO_DEPTH)
|
||||
) dmc (
|
||||
.async_reset_tag_i(dmc_rst_tag),
|
||||
.bsg_dly_tag_i(dmc_dly_tag), .bsg_dly_trigger_tag_i(dmc_dly_trigger_tag), .bsg_ds_tag_i(dmc_ds_tag),
|
||||
.dmc_p_i(dmc_config),
|
||||
.sys_reset_i(sys_reset),
|
||||
.app_addr_i(app_addr), .app_cmd_i(app_cmd), .app_en_i(app_en), .app_rdy_o(app_rdy),
|
||||
.app_wdf_wren_i(app_wdf_wren), .app_wdf_data_i(app_wdf_data), .app_wdf_mask_i(app_wdf_mask), .app_wdf_end_i(app_wdf_end), .app_wdf_rdy_o(app_wdf_rdy),
|
||||
.app_rd_data_valid_o(app_rd_data_valid), .app_rd_data_o(app_rd_data), .app_rd_data_end_o(app_rd_data_end),
|
||||
.app_ref_req_i(1'b0), .app_ref_ack_o(app_ref_ack),
|
||||
.app_zq_req_i(1'b0), .app_zq_ack_o(app_zq_ack),
|
||||
.app_sr_req_i(1'b0), .app_sr_active_o(app_sr_active),
|
||||
.init_calib_complete_o(init_calib_complete),
|
||||
.ddr_ck_p_o(ddr_ck_p), .ddr_ck_n_o(ddr_ck_n), .ddr_cke_o(ddr_cke),
|
||||
.ddr_ba_o(ddr_ba), .ddr_addr_o(ddr_addr), .ddr_cs_n_o(ddr_cs), .ddr_ras_n_o(ddr_ras), .ddr_cas_n_o(ddr_cas),
|
||||
.ddr_we_n_o(ddr_we), .ddr_reset_n_o(ddr_reset), .ddr_odt_o(ddr_odt),
|
||||
.ddr_dm_oen_o(ddr_dm_oen), .ddr_dm_o(ddr_dm),
|
||||
.ddr_dqs_p_oen_o(ddr_dqs_p_oen), .ddr_dqs_p_ien_o(ddr_dqs_p_ien), .ddr_dqs_p_o(ddr_dqs_p_out), .ddr_dqs_p_i(ddr_dqs_p_in),
|
||||
.ddr_dqs_n_oen_o(ddr_dqs_n_oen), .ddr_dqs_n_ien_o(ddr_dqs_n_ien), .ddr_dqs_n_o(ddr_dqs_n_out), .ddr_dqs_n_i(ddr_dqs_n_in),
|
||||
.ddr_dq_oen_o(ddr_dq_oen), .ddr_dq_o(ddr_dq_out), .ddr_dq_i(ddr_dq_in),
|
||||
.ui_clk_i(ui_clk),
|
||||
.dfi_clk_2x_i(dfi_clk_2x), .dfi_clk_1x_o(dfi_clk_1x),
|
||||
.ui_clk_sync_rst_o(ui_clk_sync_rst),
|
||||
.device_temp_o(device_temp)
|
||||
);
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user