OpenCores
URL https://opencores.org/ocsvn/rtftextcontroller/rtftextcontroller/trunk

Subversion Repositories rtftextcontroller

[/] [rtftextcontroller/] [trunk/] [rtl/] [verilog/] [rfTextCharRam.sv] - Blame information for rev 31

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 31 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2018-2022  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch@finitron.ca
6
//       ||
7
//
8
//
9
// BSD 3-Clause License
10
// Redistribution and use in source and binary forms, with or without
11
// modification, are permitted provided that the following conditions are met:
12
//
13
// 1. Redistributions of source code must retain the above copyright notice, this
14
//    list of conditions and the following disclaimer.
15
//
16
// 2. Redistributions in binary form must reproduce the above copyright notice,
17
//    this list of conditions and the following disclaimer in the documentation
18
//    and/or other materials provided with the distribution.
19
//
20
// 3. Neither the name of the copyright holder nor the names of its
21
//    contributors may be used to endorse or promote products derived from
22
//    this software without specific prior written permission.
23
//
24
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
//
35
// ============================================================================
36
//
37
module rfTextCharRam(clk_i, cs_i, we_i, sel_i, adr_i, dat_i, dat_o, dot_clk_i, ce_i,
38
  fontAddress_i, char_code_i, maxScanpix_i, maxscanline_i, scanline_i, bmp_o);
39
parameter pFontFile = "char_bitmaps_12x18.mem";
40
input clk_i;
41
input cs_i;
42
input we_i;
43
input [7:0] sel_i;
44
input [15:3] adr_i;
45
input [63:0] dat_i;
46
output [63:0] dat_o;
47
input dot_clk_i;
48
input ce_i;
49
input [15:0] fontAddress_i;
50
input [12:0] char_code_i;
51
input [5:0] maxScanpix_i;
52
input [5:0] maxscanline_i;
53
input [5:0] scanline_i;
54
output reg [63:0] bmp_o;
55
 
56
wire [63:0] memo;
57
reg [15:0] rcc, rcc0, rcc1, rcc2, rcc3;
58
reg [2:0] rcc200, rcc201, rcc202;
59
reg [1:0] bndx;
60
reg [63:0] bmp1;
61
//reg [7:0] bmp [0:7];
62
 
63
wire pe_cs;
64
edge_det ued1 (.rst(1'b0), .clk(clk_i), .ce(1'b1), .i(cs_i), .pe(pe_cs), .ne(), .ee());
65
 
66
reg [7:0] wea;
67
always_comb
68
        wea <= {8{we_i}} & sel_i;
69
 
70
// xpm_memory_tdpram: True Dual Port RAM
71
// Xilinx Parameterized Macro, version 2020.2
72
`ifdef VENDOR_XILINX
73
 
74
        xpm_memory_tdpram #(
75
          .ADDR_WIDTH_A(13),
76
          .ADDR_WIDTH_B(13),
77
          .AUTO_SLEEP_TIME(0),
78
          .BYTE_WRITE_WIDTH_A(8),
79
          .BYTE_WRITE_WIDTH_B(8),
80
          .CASCADE_HEIGHT(0),
81
          .CLOCKING_MODE("independent_clock"), // String
82
          .ECC_MODE("no_ecc"),            // String
83
          .MEMORY_INIT_FILE(pFontFile),   // String
84
          .MEMORY_INIT_PARAM(""),        // String
85
          .MEMORY_OPTIMIZATION("true"),   // String
86
          .MEMORY_PRIMITIVE("block"),      // String
87
          .MEMORY_SIZE(524288),
88
          .MESSAGE_CONTROL(0),
89
          .READ_DATA_WIDTH_A(64),
90
          .READ_DATA_WIDTH_B(64),
91
          .READ_LATENCY_A(2),
92
          .READ_LATENCY_B(1),
93
          .READ_RESET_VALUE_A("0"),       // String
94
          .READ_RESET_VALUE_B("0"),       // String
95
          .RST_MODE_A("SYNC"),            // String
96
          .RST_MODE_B("SYNC"),            // String
97
          .SIM_ASSERT_CHK(0),             // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
98
          .USE_EMBEDDED_CONSTRAINT(0),    // DECIMAL
99
          .USE_MEM_INIT(1),
100
          .WAKEUP_TIME("disable_sleep"),  // String
101
          .WRITE_DATA_WIDTH_A(64),
102
          .WRITE_DATA_WIDTH_B(64),
103
          .WRITE_MODE_A("no_change"),     // String
104
          .WRITE_MODE_B("no_change")      // String
105
        )
106
        xpm_memory_tdpram_inst (
107
          .dbiterra(),             // 1-bit output: Status signal to indicate double bit error occurrence
108
                                           // on the data output of port A.
109
 
110
          .dbiterrb(),             // 1-bit output: Status signal to indicate double bit error occurrence
111
                                           // on the data output of port A.
112
 
113
          .douta(dat_o),                   // READ_DATA_WIDTH_A-bit output: Data output for port A read operations.
114
          .doutb(memo),                    // READ_DATA_WIDTH_B-bit output: Data output for port B read operations.
115
          .sbiterra(),             // 1-bit output: Status signal to indicate single bit error occurrence
116
                                           // on the data output of port A.
117
 
118
          .sbiterrb(),             // 1-bit output: Status signal to indicate single bit error occurrence
119
                                           // on the data output of port B.
120
 
121
          .addra(adr_i),                   // ADDR_WIDTH_A-bit input: Address for port A write and read operations.
122
          .addrb(rcc3[15:3]),               // ADDR_WIDTH_B-bit input: Address for port B write and read operations.
123
          .clka(clk_i),                     // 1-bit input: Clock signal for port A. Also clocks port B when
124
                                           // parameter CLOCKING_MODE is "common_clock".
125
 
126
          .clkb(~dot_clk_i),               // 1-bit input: Clock signal for port B when parameter CLOCKING_MODE is
127
                                           // "independent_clock". Unused when parameter CLOCKING_MODE is
128
                                           // "common_clock".
129
 
130
          .dina(dat_i),                     // WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations.
131
          .dinb(64'h0),                     // WRITE_DATA_WIDTH_B-bit input: Data input for port B write operations.
132
          .ena(cs_i),                       // 1-bit input: Memory enable signal for port A. Must be high on clock
133
                                           // cycles when read or write operations are initiated. Pipelined
134
                                           // internally.
135
 
136
          .enb(~bndx[1]),                  // 1-bit input: Memory enable signal for port B. Must be high on clock
137
                                           // cycles when read or write operations are initiated. Pipelined
138
                                           // internally.
139
 
140
          .injectdbiterra(1'b0), // 1-bit input: Controls double bit error injection on input data when
141
                                           // ECC enabled (Error injection capability is not available in
142
                                           // "decode_only" mode).
143
 
144
          .injectdbiterrb(1'b0), // 1-bit input: Controls double bit error injection on input data when
145
                                           // ECC enabled (Error injection capability is not available in
146
                                           // "decode_only" mode).
147
 
148
          .injectsbiterra(1'b0), // 1-bit input: Controls single bit error injection on input data when
149
                                           // ECC enabled (Error injection capability is not available in
150
                                           // "decode_only" mode).
151
 
152
          .injectsbiterrb(1'b0), // 1-bit input: Controls single bit error injection on input data when
153
                                           // ECC enabled (Error injection capability is not available in
154
                                           // "decode_only" mode).
155
 
156
          .regcea(cs_i),                 // 1-bit input: Clock Enable for the last register stage on the output
157
                                           // data path.
158
 
159
          .regceb(1'b1),                 // 1-bit input: Clock Enable for the last register stage on the output
160
                                           // data path.
161
 
162
          .rsta(1'b0),                     // 1-bit input: Reset signal for the final port A output register stage.
163
                                           // Synchronously resets output port douta to the value specified by
164
                                           // parameter READ_RESET_VALUE_A.
165
 
166
          .rstb(1'b0),                     // 1-bit input: Reset signal for the final port B output register stage.
167
                                           // Synchronously resets output port doutb to the value specified by
168
                                           // parameter READ_RESET_VALUE_B.
169
 
170
          .sleep(1'b0),                   // 1-bit input: sleep signal to enable the dynamic power saving feature.
171
          .wea(wea),                                                            // WRITE_DATA_WIDTH_A/BYTE_WRITE_WIDTH_A-bit input: Write enable vector
172
                                           // for port A input data port dina. 1 bit wide when word-wide writes are
173
                                           // used. In byte-wide write configurations, each bit controls the
174
                                           // writing one byte of dina to address addra. For example, to
175
                                           // synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A
176
                                           // is 32, wea would be 4'b0010.
177
 
178
          .web(8'h00)                      // WRITE_DATA_WIDTH_B/BYTE_WRITE_WIDTH_B-bit input: Write enable vector
179
                                           // for port B input data port dinb. 1 bit wide when word-wide writes are
180
                                           // used. In byte-wide write configurations, each bit controls the
181
                                           // writing one byte of dinb to address addrb. For example, to
182
                                           // synchronously write only bits [15-8] of dinb when WRITE_DATA_WIDTH_B
183
                                           // is 32, web would be 4'b0010.
184
 
185
        );
186
 
187
`elsif VENDOR_ALTERA
188
        genvar g;
189
        generate begin : gAlteraRAM
190
                for (g = 0; g < 8; g = g + 1) begin
191
            ALTSYNCRAM #(
192
              .OPERATION_MODE("DUAL_PORT"),
193
              .WIDTH_A(8),
194
              .WIDTHAD_A(13),
195
              .WIDTH_B(8),
196
              .WIDTHAD_B(13),
197
              .READ_DURING_WRITE_MIXED_PORTS("DONT_CARE")
198
            ) charram0 (
199
              .clock0(clk_i),
200
              .clock1(clk_i),
201
 
202
              // Write port
203
              .wren_a(we_i & sel_i[g]),
204
              .address_a(adr_i),
205
              .data_a(dat_i[g*8+7:g*8]),
206
              .q_a(),
207
 
208
              // Read port
209
              .rden_b(1'b1),
210
              .address_b(adr_i),
211
              .q_b(dat_o[g*8+7:g*8])
212
            );
213
            ALTSYNCRAM #(
214
              .OPERATION_MODE("DUAL_PORT"),
215
              .WIDTH_A(8),
216
              .WIDTHAD_A(13),
217
              .WIDTH_B(8),
218
              .WIDTHAD_B(13),
219
              .READ_DURING_WRITE_MIXED_PORTS("DONT_CARE")
220
            ) charram1 (
221
              .clock0(clk_i),
222
              .clock1(~dot_clk_i),
223
 
224
              // Write port
225
              .wren_a(we_i & sel_i[g]),
226
              .address_a(adr_i),
227
              .data_a(dat_i[g*8+7:g*8]),
228
              .q_a(),
229
 
230
              // Read port
231
              .rden_b(1'b1),
232
              .address_b(rcc3[15:3]),
233
              .q_b(memo[g*8+7:g*8])
234
            );
235
          end
236
        end
237
        endgenerate
238
`else
239
        /* ToDo: implement the rest of this */
240
        reg [63:0] mem [0:8191];
241
        always_ff @(posedge clk_i)
242
                begin
243
                end
244
        always_comb
245
        begin
246
                $display("No RAM vendor selected.");
247
                $finish();
248
        end
249
`endif
250
 
251
reg [3:0] scan_width;   // scan width in bytes rounded up
252
always_comb
253
        scan_width = maxScanpix_i[5:3] + |maxScanpix_i[2:0];
254
reg [9:0] char_size;    // character size in bytes
255
always_comb
256
        char_size = maxscanline_i * scan_width;
257
reg [6:0] char_size8;   // character size in octa-bytes
258
always_comb
259
        char_size8 = char_size[9:3] + |char_size[2:0];
260
 
261
// Char code is already delated two clocks relative to ce
262
// Assume that characters are always going to be at least four clocks wide.
263
// Clock #0
264
always_ff @(posedge dot_clk_i)
265
  if (ce_i)
266
    rcc <= char_code_i*{char_size8,3'b0}+scanline_i*scan_width;
267
// Provide some pipeline stages for the previous multiplies and adds
268
// Clock #1
269
always_ff @(posedge dot_clk_i)
270
        rcc0 <= rcc;
271
always_ff @(posedge dot_clk_i)
272
        rcc1 <= rcc0;
273
always_ff @(posedge dot_clk_i)
274
        rcc2 <= rcc1;
275
// Clock #2
276
always_ff @(posedge dot_clk_i)
277
  if (ce_i) begin
278
    rcc3 <= {fontAddress_i[15:3],3'b0}+rcc2;
279
    bndx <= 'd0;
280
  end
281
  else begin
282
        case(bndx)
283
        2'd0:   bmp1 <= memo >> {rcc3[2:0],3'b0};                                                                        // right half
284
        2'd1:   bmp1 <= (memo << {4'd8-rcc3[2:0],3'b0}) | bmp1;         // left half
285
                default:        ;
286
                endcase
287
                if (bndx < 2'd2)
288
                        bndx <= bndx + 2'd1;
289
                rcc3 <= rcc3 + 4'd8;
290
        /*
291
    if (bndx[2:0] <= maxScanpix_i[5:3]) begin
292
      bmp[bndx[2:0]] <= memo8;
293
      rcc1 <= rcc1 + 1'd1;
294
      bndx <= bndx + 1'd1;
295
    end
296
    */
297
  end
298
always @(posedge dot_clk_i)
299
  if (ce_i)
300
          bmp_o <= bmp1;//{bmp[7],bmp[6],bmp[5],bmp[4],bmp[3],bmp[2],bmp[1],bmp[0]};
301
 
302
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.