x393  1.0
FPGAcodeforElphelNC393camera
cmd_seq_mux.v
Go to the documentation of this file.
1 
40 `timescale 1ns/1ps
41 
42 module cmd_seq_mux#(
43  parameter CMDSEQMUX_ADDR = 'h702, // only status control
44  parameter CMDSEQMUX_MASK = 'h7ff,
45  parameter CMDSEQMUX_STATUS = 'h38,
46  parameter AXI_WR_ADDR_BITS=14
47 )(
48  input mrst, // global system reset
49  input mclk, // global system clock
50  // programming interface
51  input [7:0] cmd_ad, // byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3
52  input cmd_stb, // strobe (with first byte) for the command a/d
53  output [7:0] status_ad, // status address/data - up to 5 bytes: A - {seq,status[1:0]} - status[2:9] - status[10:17] - status[18:25]
54  output status_rq, // input request to send status downstream
55  input status_start, // Acknowledge of the first status packet byte (address)
56 
57  // Sensor channel 0
58  input [ 3:0] frame_num0, // @posedge mclk
59  input [AXI_WR_ADDR_BITS-1:0] waddr0, // write address, valid with wr_en_out
60  input wr_en0, // write enable
61  input [31:0] wdata0, // write data, valid with waddr_out and wr_en_out
62  output ackn0, // command sequencer address/data accepted
63  input is0, // interrupt status (not masked)
64  input im0, // interrupt mask
65  // Sensor channel 1
66  input [ 3:0] frame_num1, // @posedge mclk
67  input [AXI_WR_ADDR_BITS-1:0] waddr1, // write address, valid with wr_en_out
68  input wr_en1, // write enable
69  input [31:0] wdata1, // write data, valid with waddr_out and wr_en_out
70  output ackn1, // command sequencer address/data accepted
71  input is1, // interrupt status (not masked)
72  input im1, // interrupt mask
73  // Sensor channel 2
74  input [ 3:0] frame_num2, // @posedge mclk
75  input [AXI_WR_ADDR_BITS-1:0] waddr2, // write address, valid with wr_en_out
76  input wr_en2, // write enable
77  input [31:0] wdata2, // write data, valid with waddr_out and wr_en_out
78  output ackn2, // command sequencer address/data accepted
79  input is2, // interrupt status (not masked)
80  input im2, // interrupt mask
81  // Sensor channel 3
82  input [ 3:0] frame_num3, // @posedge mclk
83  input [AXI_WR_ADDR_BITS-1:0] waddr3, // write address, valid with wr_en_out
84  input wr_en3, // write enable
85  input [31:0] wdata3, // write data, valid with waddr_out and wr_en_out
86  output ackn3, // command sequencer address/data accepted
87  input is3, // interrupt status (not masked)
88  input im3, // interrupt mask
89  // mux output
90  output reg [AXI_WR_ADDR_BITS-1:0] waddr_out, // write address, valid with wr_en_out
91  output wr_en_out, // write enable
92  output reg [31:0] wdata_out, // write data, valid with waddr_out and wr_en_out
93  input ackn_out // command sequencer address/data accepted
94 );
95  wire [3:0] wr_en = {wr_en3 & ~ackn3, wr_en2 & ~ackn2, wr_en1 & ~ackn1, wr_en0 & ~ackn0};
96  wire [15:0] pri_one_rr; // round robin priority
97  wire [3:0] pri_one;
98  reg [1:0] chn_r; // last served channel
99  wire rq_any;
100  wire [1:0] pri_enc_w;
101  reg full_r;
102  wire ackn_w; //pre-acknowledge of one of the channels
103  reg [3:0] ackn_r;
104 
105  wire [3:0] is = {is3, is2, is1, is0};
106  wire [3:0] im = {im3, im2, im1, im0};
107 
108  assign pri_one_rr = {wr_en[3] & ~(|wr_en[2:0]), wr_en[2]&~(|wr_en[1:0]), wr_en[1] & wr_en[0], wr_en[0],
109  wr_en[3], wr_en[2]&~(|wr_en[1:0])&wr_en[3], wr_en[1] & ~ wr_en[3] & wr_en[0], wr_en[0] & ~ wr_en[3],
110  wr_en[3] & ~ wr_en[2], wr_en[2], wr_en[1] & ~(|wr_en[3:2]) & wr_en[0], wr_en[0] & ~(|wr_en[3:2]),
111  wr_en[3] & ~(|wr_en[2:1]), wr_en[2] & ~wr_en[1], wr_en[1], wr_en[0] & ~(|wr_en[3:1])};
112 
113 
114  assign pri_one = pri_one_rr[chn_r * 4 +: 4];
115  assign rq_any= |wr_en;
116  assign pri_enc_w ={pri_one[3] | pri_one[2],
117  pri_one[3] | pri_one[1]};
118  assign wr_en_out = full_r;
119  assign {ackn3, ackn2, ackn1, ackn0} = ackn_r;
120  assign ackn_w = rq_any && (!full_r || ackn_out);
121 
122  always @(posedge mclk) begin
123  if (mrst) full_r <= 0;
124  else if (rq_any) full_r <= 1;
125  else if (ackn_out) full_r <= 0;
126 
127  if (mrst) ackn_r <=0;
128  else ackn_r <= {4{ackn_w}} & { pri_enc_w[1] & pri_enc_w[0],
129  pri_enc_w[1] & ~pri_enc_w[0],
130  ~pri_enc_w[1] & pri_enc_w[0],
131  ~pri_enc_w[1] & ~pri_enc_w[0]};
132  end
133 
134  always @(posedge mclk) begin
135 
136  if (ackn_w) begin
137  chn_r <= pri_enc_w;
138  case (pri_enc_w)
139  2'h0:begin
140  waddr_out <= waddr0;
141  wdata_out <= wdata0;
142  end
143  2'h1:begin
144  waddr_out <= waddr1;
145  wdata_out <= wdata1;
146  end
147  2'h2:begin
148  waddr_out <= waddr2;
149  wdata_out <= wdata2;
150  end
151  2'h3:begin
152  waddr_out <= waddr3;
153  wdata_out <= wdata3;
154  end
155  endcase
156 
157  end
158  end
159 
160  // Only command is to program status, status combines frame numbers (4 bit each)
161  wire [7:0] cmd_data;
164  .ADDR (CMDSEQMUX_ADDR),
165  .ADDR_MASK (CMDSEQMUX_MASK),
166  .NUM_CYCLES (3), // 6), // TODO: Is it OK to specify less bits than on transmit side? Seems yes
167  .ADDR_WIDTH (1),
168  .DATA_WIDTH (8) //,32)
169 
170  ) cmd_deser_32bit_i (
171  .rst (1'b0), //rst), // input
172  .clk (mclk), // input
173  .srst (mrst), // input
174  .ad (cmd_ad), // input[7:0]
175  .stb (cmd_stb), // input
176  .addr (), // output[0:0]
177  .data (cmd_data), // output[31:0]
178  .we (cmd_status) // output
179  );
180 
182  .STATUS_REG_ADDR (CMDSEQMUX_STATUS),
183  .PAYLOAD_BITS (26),
184  .REGISTER_STATUS (1)
185  ) status_generate_cmd_seq_mux_i (
186  .rst (1'b0), //rst), // input
187  .clk (mclk), // input
188  .srst (mrst), // input
189  .we (cmd_status), // input
190  .wd (cmd_data[7:0]), // input[7:0]
191  .status ({im, is, frame_num3, frame_num2, frame_num1, frame_num0, 2'b0}), // input[18:0] // 2 LSBs - may add "real" status
192  .ad (status_ad), // output[7:0]
193  .rq (status_rq), // output
194  .start (status_start) // input
195  );
196 
197 
198 
199 endmodule
200 
[ 3:0] 10230frame_num0
Definition: cmd_seq_mux.v:58
10270ackn_rreg[3:0]
Definition: cmd_seq_mux.v:103
[AXI_WR_ADDR_BITS-1:0] 10231waddr0
Definition: cmd_seq_mux.v:59
10264pri_onewire[3:0]
Definition: cmd_seq_mux.v:97
[31:0] 10240wdata1
Definition: cmd_seq_mux.v:69
reg [AXI_WR_ADDR_BITS-1:0] 10258waddr_out
Definition: cmd_seq_mux.v:90
[7:0] 10227status_ad
Definition: cmd_seq_mux.v:53
cmd_deser_32bit_i cmd_deser
Definition: cmd_seq_mux.v:163
10267pri_enc_wwire[1:0]
Definition: cmd_seq_mux.v:100
10263pri_one_rrwire[15:0]
Definition: cmd_seq_mux.v:96
reg [31:0] 10260wdata_out
Definition: cmd_seq_mux.v:92
[ 3:0] 10251frame_num3
Definition: cmd_seq_mux.v:82
[31:0] 10247wdata2
Definition: cmd_seq_mux.v:77
status_generate_cmd_seq_mux_i status_generate
Definition: cmd_seq_mux.v:181
[AXI_WR_ADDR_BITS-1:0] 10238waddr1
Definition: cmd_seq_mux.v:67
10272imwire[3:0]
Definition: cmd_seq_mux.v:106
[31:0] 10233wdata0
Definition: cmd_seq_mux.v:61
[ADDR_MASK2!=0?2:ADDR_MASK1!=0?1:0:0] 9935we
Definition: cmd_deser.v:60
10273cmd_datawire[7:0]
Definition: cmd_seq_mux.v:161
10220CMDSEQMUX_MASK'h7ff
Definition: cmd_seq_mux.v:44
[DATA_WIDTH-1:0] 9934data
Definition: cmd_deser.v:59
10266rq_anywire
Definition: cmd_seq_mux.v:99
10271iswire[3:0]
Definition: cmd_seq_mux.v:105
[AXI_WR_ADDR_BITS-1:0] 10245waddr2
Definition: cmd_seq_mux.v:75
10265chn_rreg[1:0]
Definition: cmd_seq_mux.v:98
[7:0] 10225cmd_ad
Definition: cmd_seq_mux.v:51
10221CMDSEQMUX_STATUS'h38
Definition: cmd_seq_mux.v:45
[7:0] 9931ad
Definition: cmd_deser.v:56
[ADDR_WIDTH-1:0] 9933addr
Definition: cmd_deser.v:58
10274cmd_statuswire
Definition: cmd_seq_mux.v:162
[ 3:0] 10237frame_num1
Definition: cmd_seq_mux.v:66
[ 3:0] 10244frame_num2
Definition: cmd_seq_mux.v:74
10269ackn_wwire
Definition: cmd_seq_mux.v:102
10219CMDSEQMUX_ADDR'h702
Definition: cmd_seq_mux.v:43
10222AXI_WR_ADDR_BITS14
Definition: cmd_seq_mux.v:46
[ALL_BITS-1:0] 10777status
10262wr_enwire[3:0]
Definition: cmd_seq_mux.v:95
[31:0] 10254wdata3
Definition: cmd_seq_mux.v:85
[AXI_WR_ADDR_BITS-1:0] 10252waddr3
Definition: cmd_seq_mux.v:83