x393  1.0
FPGAcodeforElphelNC393camera
dct_chen_transpose.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
42  parameter WIDTH = 24
43  )(
44  input clk,
45  input rst,
46  input [WIDTH -1:0] din, // pre2_start-X-F4-X-F2-X-F6-F5-F0-F3-X-F1-X-F7
47  input pre2_start, // Two cycles ahead of F4. Next one should start either at exactly 64 cycles, or >=68 cycles from the previous one
48  output [2*WIDTH -1:0] dout_10_32_76_54, // Concatenated/reordered output data {x[1],x[0]}/{x[3],x[2]}/ {x[7],x[6]}/{x[5],x[4]}
49  output reg start_out,
50  output reg en_out // to be sampled when start_out is expected
51 );
52  reg [6:0] wcntr; // write counter, used to calculate write address (2 pages of 64 words), that will be valid next cycle
53  wire [2:0] wrow = wcntr[5:3];
54  wire [2:0] wcol = wcntr[2:0];
55  wire wpage;
56 
57  reg wcol13; // columns 1 and 3 (special)
58  wire [3:0] wrow_mod; // effective row, including modifier for wpage
59  wire [1:0] wcol01_mod = wcol[1:0] - wcol[2];
60  reg [6:0] waddr;
61  wire pre2_stop;
62  reg [WIDTH-1:0] transpose_ram[0:127];
63  reg pre_we_r;
64  reg we_r;
65  reg [5:0] rcntr = 6'h3f; // read counter
66  reg [5:0] raddr; // read counter, addresses dual words
67  reg re_r;
68  reg regen_r;
69  reg [2*WIDTH-1:0] ram_reg;
70  reg [2*WIDTH-1:0] ram_reg2;
71  wire pre_rstart_w = wcntr[5:0] == 61;
72  reg [1:0] rstop_r;
73  reg first_after_pause; // first block after pause - do not write 2 items to the "past"
74 
75  assign wpage = wcntr[6] ^ wrow_mod[3]; // previous page for row 0, col 1 & 3
76  assign wrow_mod = {1'b0, wrow} - wcol13;
77  assign dout_10_32_76_54 = ram_reg2;
78  // TODO: prevent writing to previous page after pause!
79  always @(posedge clk) begin
80  wcol13 <= pre_we_r & ~wcol[0] & ~wcol[2];
81  waddr[0] <= wrow_mod[0] ^ wrow_mod[2];
82  waddr[1] <= wcol[0];
83  waddr[2] <= wcol01_mod[1];
84  waddr[3] <= ~wcol01_mod[0] ^ wcol01_mod[1];
85  waddr[4] <= wrow_mod[1] ^ wrow_mod[2];
86  waddr[5] <= wrow_mod[2];
87  waddr[6] <= wpage;
88 
89  if (rst) pre_we_r <= 0;
90  else if (pre2_start) pre_we_r <= 1;
91  else if (pre2_stop) pre_we_r <= 0;
92 
93  if (rst) wcntr <= 0;
94  else if (pre_we_r) wcntr <= wcntr + 1; // including page, should be before 'if (pre2_start)'
95  else if (pre2_start) wcntr <= {wcntr[6], 6'b0}; // if happens during pre_we_r - will be ignored, otherwise (after pause) will zero in-page adderss
96 
97  we_r <= pre_we_r && (!first_after_pause || !wcol13 || (|wrow)); // do not write first after pause to the "past"
98 
99  if (we_r) transpose_ram[waddr] <= din;
100 
101  if (rst) rcntr <= ~0;
102  else if (pre_rstart_w) rcntr <= 0;
103  else if (!(&rcntr)) rcntr <= rcntr + 1;
104 
105  re_r <= ~rcntr[2];
106  regen_r <= re_r;
107 
108  if (rcntr == 0) raddr[5] <= wcntr[6]; // page
109  raddr[4:0] <= {rcntr[1:0],rcntr[5:3]};
110 
111  if (re_r) ram_reg <= {transpose_ram[2*raddr+1],transpose_ram[2*raddr]}; // See if it will correctly infer
112  if (regen_r) ram_reg2 <= ram_reg;
113 
114  if (rst || pre_rstart_w) rstop_r <= 0;
115  else if (&rcntr) rstop_r <= {rstop_r[0], 1'b1};
116 
117  start_out <= (rcntr == 1);
118 
119  if (rst) en_out <= 0;
120  else if (rcntr == 1) en_out <= 1;
121  else if (rstop_r[1]) en_out <= 0;
122 
123  if (rst) first_after_pause <= 0;
124  else if (pre2_start && !we_r) first_after_pause <= 1;
125  else if (&wcntr[5:0]) first_after_pause <= 0;
126 
127  end
128 
129  dly01_16 dly01_16_stop_i (
130  .clk (clk), // input
131  .rst (rst), // input
132  .dly (4'h3), // input[3:0]
133  .din (&wcntr[5:0] && !pre2_start), // input
134  .dout (pre2_stop) // output
135  );
136 
137 
138 /*
139 min latency == 60, // adding 1 for read after write in RAM
140 max latency = 83 (when using a 2-page buffer)
141 wseq=(0x08, 0x62, 0x04, 0x6e, 0x0c, 0x0a, 0x00, 0x06,
142  0x09, 0x02, 0x05, 0x0e, 0x0d, 0x0b, 0x01, 0x07,
143  0x18, 0x03, 0x14, 0x0f, 0x1c, 0x1a, 0x10, 0x16,
144  0x19, 0x12, 0x15, 0x1e, 0x1d, 0x1b, 0x11, 0x17,
145  0x39, 0x13, 0x35, 0x1f, 0x3d, 0x3b, 0x31, 0x37,
146  0x38, 0x33, 0x34, 0x3f, 0x3c, 0x3a, 0x30, 0x36,
147  0x29, 0x32, 0x25, 0x3e, 0x2d, 0x2b, 0x21, 0x27,
148  0x28, 0x23, 0x24, 0x2f, 0x2c, 0x2a, 0x20, 0x26)
149 rseq = (0x00,0x10,0x20,0x30,-1,-1,-1,-1,
150  0x02,0x12,0x22,0x32,-1,-1,-1,-1,
151  0x04,0x14,0x24,0x34,-1,-1,-1,-1,
152  0x06,0x16,0x26,0x36,-1,-1,-1,-1,
153  0x08,0x18,0x28,0x38,-1,-1,-1,-1,
154  0x0a,0x1a,0x2a,0x3a,-1,-1,-1,-1,
155  0x0c,0x1c,0x2c,0x3c,-1,-1,-1,-1,
156  0x0e,0x1e,0x2e,0x3e,-1,-1,-1,-1)
157 
158 */
159 endmodule
160 
10329dout
Definition: dly01_16.v:46
[3:0] 10327dly
Definition: dly01_16.v:44
[2*WIDTH -1:0] 3318dout_10_32_76_54
dly01_16_stop_i dly01_16
3337ram_regreg[2*WIDTH-1:0]
10326rst
Definition: dly01_16.v:43
3338ram_reg2reg[2*WIDTH-1:0]
[WIDTH -1:0] 3316din
[0:127] 3330transpose_ramreg[WIDTH-1:0]
10325clk
Definition: dly01_16.v:42
10328din
Definition: dly01_16.v:45