/******************************************************************************* * Module: scheduler16 * Date:2015-01-09 * Author: andrey * Description: 16-channel programmable DDR memory access scheduler * * Copyright (c) 2015 Elphel, Inc. * scheduler16.v is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * scheduler16.v is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . *******************************************************************************/ `timescale 1ns/1ps module scheduler16 #( parameter width=16, // counter number of bits parameter n_chn=16 // number of channels )( input rst, input clk, input [n_chn-1:0] chn_en, // channel enable mask input [n_chn-1:0] want_rq, // both want_rq and need_rq should go inactive after being granted input [n_chn-1:0] need_rq, input en_schedul, // needs to be disabled before next access can be scheduled output need, // granted access is "needed" one, not just "wanted" output grant, // single-cycle granted channel access output [3:0] grant_chn, // granted channel number, valid with grant, stays valid until en_schedul is deasserted input [3:0] pgm_addr, // channel address to program priority input [width-1:0] pgm_data, // priority data for the channel input pgm_en // enable programming priority data (use different clock?) ); reg [width*n_chn-1:0] pri_reg; // priorities for each channel (start values for priority counters) reg [n_chn-1:0] want_conf, need_conf,need_want_conf,need_want_conf_d; wire [n_chn-1:0] want_set,need_set; // reg [n_chn-1:0] want_set_r,need_set_r; reg [n_chn-1:0] want_need_set_r; reg need_r, need_r2; reg [width*n_chn-1:0] sched_state; // priority counters for each channel wire need_some=|(need_rq & chn_en); wire [n_chn-1:0] next_want_conf,next_need_conf; wire [n_chn-1:0] need_want_conf_w; wire [3:0] index; // channel index to select wire index_valid; // selected index valid ("needed" or "wanted") reg grant_r; // 1 cycle long reg grant_sent; // turns on after grant, until en_schedul is de-asserted reg [3:0] grant_chn_r; wire grant_w; assign grant=grant_r; assign grant_chn=grant_chn_r; assign grant_w=en_schedul && index_valid && !grant_sent && !grant; // Setting priority for each channel generate genvar i; for (i=0;i