x393  1.0
FPGAcodeforElphelNC393camera
scheduler16.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
41 module scheduler16 #(
42  parameter width=16, // counter number of bits
43  parameter n_chn=16 // number of channels
44 )(
45  input mrst,
46  input clk,
47  input [n_chn-1:0] chn_en, // channel enable mask
48  input [n_chn-1:0] want_rq, // both want_rq and need_rq should go inactive after being granted
49  input [n_chn-1:0] need_rq,
50  input en_schedul, // needs to be disabled before next access can be scheduled
51  output need, // granted access is "needed" one, not just "wanted"
52  output grant, // single-cycle granted channel access
53  output [3:0] grant_chn, // granted channel number, valid with grant, stays valid until en_schedul is deasserted
54  input [3:0] pgm_addr, // channel address to program priority
55  input [width-1:0] pgm_data, // priority data for the channel
56  input pgm_en // enable programming priority data (use different clock?)
57 );
58  reg [width*n_chn-1:0] pri_reg; // priorities for each channel (start values for priority counters)
60  wire [n_chn-1:0] want_set,need_set;
61 // reg [n_chn-1:0] want_set_r,need_set_r;
64  reg [width*n_chn-1:0] sched_state; // priority counters for each channel
67  wire [n_chn-1:0] need_want_conf_w;
68  wire [3:0] index; // channel index to select
69  wire index_valid; // selected index valid ("needed" or "wanted")
70  reg grant_r; // 1 cycle long
71  reg grant_sent; // turns on after grant, until en_schedul is de-asserted
72  reg [3:0] grant_chn_r;
73  wire grant_w;
74  assign grant=grant_r;
75  assign grant_chn=grant_chn_r;
76  assign grant_w=en_schedul && index_valid && !grant_sent && !grant;
77 // Setting priority for each channel
78  generate
79  genvar i;
80  for (i=0;i<n_chn;i=i+1) begin: pri_reg_block
81  always @ (posedge clk) begin
82  if (mrst) pri_reg[width*i +: width] <= 0;
83  else if (pgm_en && (pgm_addr==i)) pri_reg[width*i +: width] <= pgm_data;
84  end
85  end
86  endgenerate
87 
88 // priority 1-hot encoders to make sure only one want/need request is "confirmed" in each clock cycle
89 // TODO: Make pri1hot16 parameter-configurable to be able to change priorities later
90  pri1hot16 i_pri1hot16_want( // priority encoder, 1-hot output (lowest bit has highest priority)
91  .in(want_rq & ~want_conf & chn_en),
92  .out(want_set),
93  .some());
94  pri1hot16 i_pri1hot16_need(
95  .in(need_rq & ~need_conf & chn_en),
96  .out(need_set),
97  .some());
98 
102  always @(posedge clk) begin
103  if (mrst) begin
104  want_conf <= 0;
105  need_conf <= 0;
106  end else begin
109  need_want_conf <= need_want_conf_w; // need_some? next_need_conf: next_want_conf;
110  need_want_conf_d <= need_want_conf & need_want_conf_w; // delay for on, no delay for off
111  end
112  end
113  always @ (posedge clk) begin
114 // want_set_r<=want_set;
115 // need_set_r<=need_set;
117  need_r <= need_some;
118  need_r2 <= need_r;
119  end
120  // TODO: want remains, need is removed (both need and want should be deactivated on grant!)
121  // Block that sets initial process state and increments it on every change of the requests
122  generate
123  genvar i1;
124  for (i1=0;i1<16;i1=i1+1) begin: sched_state_block
125 // always @ (posedge rst or posedge clk) begin
126  always @ (posedge clk) begin
127 // if (rst) sched_state[width*i1 +: width] <= 0; // not needed?
128 // else
129  begin
130 // if (want_set_r[i1] || need_set_r[i1]) sched_state[width*i1 +: width] <= pri_reg[width*i1 +: width];
131  if (want_need_set_r[i1]) sched_state[width*i1 +: width] <= pri_reg[width*i1 +: width];
132  // increment, but do not roll over
133  else if (&sched_state[width*i1 +: width] == 0) sched_state[width*i1 +: width] <= sched_state[width*i1 +: width]+1;
134  end
135  end
136  end
137  endgenerate
138  // Select the process to run
139  index_max_16 #(width) i_index_max_16(
140  .clk (clk),
141  .values (sched_state),
143  .need_in (need_r2),
144  .index (index[3:0]),
145  .valid (index_valid),
146  .need_out (need));
147  always @(posedge clk) begin
148  if (mrst) begin
149  grant_r <=0;
150  grant_sent <=0;
151  grant_chn_r <=0;
152  end else begin
153  grant_r <= grant_w; // en_schedul && index_valid && !grant_sent;
155  if (grant_w) grant_chn_r <= index[3:0];
156  end
157  end
158 
159 endmodule
160 
6660grant_chn_rreg[3:0]
Definition: scheduler16.v:72
6647need_setwire[n_chn-1:0]
Definition: scheduler16.v:60
6653next_want_confwire[n_chn-1:0]
Definition: scheduler16.v:66
6655need_want_conf_wwire[n_chn-1:0]
Definition: scheduler16.v:67
[16*width-1:0] 10556values
Definition: index_max_16.v:45
i_pri1hot16_need pri1hot16
Definition: scheduler16.v:94
6644need_want_confreg[n_chn-1:0]
Definition: scheduler16.v:59
6661grant_wwire
Definition: scheduler16.v:73
[n_chn-1:0] 6631chn_en
Definition: scheduler16.v:47
[n_chn-1:0] 6633need_rq
Definition: scheduler16.v:49
6642want_confreg[n_chn-1:0]
Definition: scheduler16.v:59
i_index_max_16 index_max_16
Definition: scheduler16.v:139
6641pri_regreg[width*n_chn-1:0]
Definition: scheduler16.v:58
6646want_setwire[n_chn-1:0]
Definition: scheduler16.v:60
[3:0] 6637grant_chn
Definition: scheduler16.v:53
[3:0] 6638pgm_addr
Definition: scheduler16.v:54
6656indexwire[3:0]
Definition: scheduler16.v:68
6652need_somewire
Definition: scheduler16.v:65
6651sched_statereg[width*n_chn-1:0]
Definition: scheduler16.v:64
6648want_need_set_rreg[n_chn-1:0]
Definition: scheduler16.v:62
[width-1:0] 6639pgm_data
Definition: scheduler16.v:55
[15:0] 10719out
Definition: pri1hot16.v:43
[15:0] 10718in
Definition: pri1hot16.v:42
6645need_want_conf_dreg[n_chn-1:0]
Definition: scheduler16.v:59
6643need_confreg[n_chn-1:0]
Definition: scheduler16.v:59
6657index_validwire
Definition: scheduler16.v:69
6654next_need_confwire[n_chn-1:0]
Definition: scheduler16.v:66
6658grant_rreg
Definition: scheduler16.v:70
6650need_r2reg
Definition: scheduler16.v:63
6659grant_sentreg
Definition: scheduler16.v:71
[15:0] 10557mask
Definition: index_max_16.v:46
[n_chn-1:0] 6632want_rq
Definition: scheduler16.v:48
[ 3:0] 10559index
Definition: index_max_16.v:48