Hiho,
erster Beitrag. Daher fröhliches HALLO an alle Beteiligten.
Seit einigen Wochen beschäftige ich mich mit FPGA Design mit Verilog und
als ich mir letztens folgende RTL Schematic angesehen habe, war ich
etwas ratlos.
Was passiert auf dem Bild im Anhang?
In den Output UND Input vom MUX fließt Strom hinein? Und in den Ausgang
vom FF?? Sehr merkwürdig.
Ich vermute, dass die Verwendung mehrerer nonblocking Assignments im
selben Always-Block auf die selbe Variable daran Schuld sein könnten.
Laut Standard ist das legitim und das letzte Assignment gewinnt. Aber
vllt. zerschießt das ja die Synthese?
Danke und beste Grüße,
Thomy
EDIT: hier der Code:
Im Grunde greifen mehrere prime-Module, die per generate erzeugt wurden,
später im always-Block auf das uart-Modul zu, und ich vermute, dadurch
entsteht die verrückte Schematic.
1 | `timescale 1ns/1ns
|
2 |
|
3 |
|
4 | // number of parallel prime solvers
|
5 | `define CNT 5
|
6 |
|
7 |
|
8 | // start of counter module
|
9 | module counter(rawclk,
|
10 | key,
|
11 | led,
|
12 | TMP_SCL,
|
13 | TMP_SDA,
|
14 | TMP_ALERT,
|
15 | RxD,
|
16 | TxD);
|
17 | // ports
|
18 | input wire TMP_SCL, TMP_SDA, TMP_ALERT, RxD;
|
19 | input wire rawclk;
|
20 | input wire [1:0] key;
|
21 | output wire TxD;
|
22 | output reg [3:0] led = 4'b0;
|
23 |
|
24 | // parameters
|
25 | parameter IDLE = 2'b00,
|
26 | CALC = 2'b01,
|
27 | COUNT = 2'b10;
|
28 |
|
29 | // pll
|
30 | wire clk;
|
31 | clock myclk(.CLK_IN1(rawclk),
|
32 | .CLK_OUT1(clk));
|
33 |
|
34 | // prime module
|
35 | reg reset = 1'b0, reset2 = 1'b0;
|
36 | reg [ 2 * `CNT - 1:0] state;
|
37 | reg [32 * `CNT - 1:0] counter;
|
38 | reg [ `CNT - 1:0] runprime;
|
39 | wire [2 * `CNT - 1:0] isprime;
|
40 |
|
41 | genvar i;
|
42 | generate
|
43 | for (i = 0; i < `CNT; i = i + 1)
|
44 | begin: COUNTERS
|
45 | prime pr(.clk(clk),
|
46 | .reset(reset2),
|
47 | .num(counter[i * 32+:32]),
|
48 | .run(runprime[i]),
|
49 | .isprime(isprime[i * 2+:2]));
|
50 | end
|
51 | endgenerate
|
52 |
|
53 | // init prime params
|
54 | integer k;
|
55 | initial
|
56 | begin
|
57 | for (k = 0; k < `CNT; k = k + 1)
|
58 | begin
|
59 | counter[k * 32+:32] = 32'd2 + k;
|
60 | runprime[k] = 1'b0;
|
61 | state[2 * k+:2] = IDLE;
|
62 | end
|
63 | end
|
64 |
|
65 | // uart sender
|
66 | wire sendbusy;
|
67 | reg sendrun = 1'b0;
|
68 | reg [7:0] senddata = 8'b0;
|
69 | uartsend send(.clk(clk),
|
70 | .reset(reset2),
|
71 | .data(senddata),
|
72 | .run(sendrun),
|
73 | .txout(TxD),
|
74 | .busy(sendbusy));
|
75 |
|
76 | // always block
|
77 | always@(posedge clk)
|
78 | begin
|
79 | reset <= |key;
|
80 | reset2 <= reset;
|
81 | sendrun <= 1'b0;
|
82 |
|
83 | for (k = 0; k < `CNT; k = k + 1)
|
84 | begin
|
85 | if (reset2)
|
86 | begin
|
87 | counter[k * 32+:32] <= 32'd2 + k;
|
88 | runprime[k] <= 1'b0;
|
89 | state[2 * k+:2] <= IDLE;
|
90 | led <= 4'b1010;
|
91 | sendrun <= 1'b0;
|
92 | senddata <= 8'b0;
|
93 | end
|
94 | else
|
95 | begin
|
96 | runprime[k] <= 1'b0;
|
97 |
|
98 | case (state[2 * k+:2])
|
99 | IDLE:
|
100 | begin
|
101 | runprime[k] <= 1'b1;
|
102 | state[2 * k+:2] <= CALC;
|
103 | end
|
104 | CALC:
|
105 | begin
|
106 | if (isprime[k * 2+:2] != COUNTERS[0].pr.UNKNOWN)
|
107 | begin
|
108 | if (isprime[k * 2+:2] == COUNTERS[0].pr.FOUND)
|
109 | begin
|
110 | $display("found: %d", counter[k * 32+:32]);
|
111 | led <= counter[k * 32 + 1+:4];
|
112 |
|
113 | if (sendbusy == 1'b0)
|
114 | begin
|
115 | senddata <= counter[k * 32+:8];
|
116 | sendrun <= 1'b1;
|
117 | end
|
118 | end
|
119 | state[2 * k+:2] <= COUNT;
|
120 | end
|
121 | end
|
122 | COUNT:
|
123 | begin
|
124 | counter[k * 32+:32] <= (counter[k * 32+:32] > 32'hFFFFFFFF - `CNT) ?
|
125 | 32'd2 + k : counter[k * 32+:32] + `CNT;
|
126 | state[2 * k+:2] <= IDLE;
|
127 | end
|
128 | default:
|
129 | state[2 * k+:2] <= IDLE;
|
130 | endcase
|
131 | end // for
|
132 | end // reset
|
133 | end // always
|
134 |
|
135 | endmodule
|