Pastel
Member level 3
Hi guys!
It's been a while...
I'm digging into an earlier project in which I started using arrays in order
to generate a sinewave from an external DAC. That was my very first project,
and now I'm trying to make it better.
Before I forget: I'm working on a MAX10M50DAF484C8G, quite an impressive beast.
I'm working on Linux Ubuntu 20.04, and the quartus prime version is also 20.
The latest, I guess.
What I was doing previously was, after generating a 24-bit data file (sine24_4k.hex),
declaring an array reg signed[23:0] signalrom[4095:0];
Basically it worked, but I understood recently that this doesn't use memory blocks
but instead makes everything from logic elements, so I thought it would be better
to shift to existing IP. There is apparenlty what I need in Library -> On Chip Memory
-> ROM: 2port. What I'm thinking is using an array as I did earlier, and interpolate
2 consecutive values to get the accuracy I need.
Ok, after this long preamble, I wrote this.I used only a top module and tried to
instantiate a memory called sig_rom.
There are 3 modes of calculation. (CALC_SWITCH on the first line).
When 0, I simply output the 16-bit upper value of a 24 bit counter. This one works
exactly as intended, I can observe a sawtooth on the scope, and the frequency is
50 MHZ / 65536 = 732Hz.
Then I wanted to verify the addresses for the memory. They should be 12 bit, so I
extract exactly 12 bits from the same 24 bit counter, to get lindex and rindex, the
indices of the 2 values I would like to extract. In order to see the difference of the
2 waves, I shift the rindex value by 1/4 of the array, therefore I expect to get the
exact same frequency as above (732Hz), but one of the 2 sawtooths will be shifted.
Experiment, that's exactly what I observe, therefore I guess lindex and rindex are
right.
Last, I have instantiated the memory, using 2 registers da and db (DA and DB are the
outputs, da and db are the outputs of the memory). So I guess the memory should spit
values addressed by lindex and rindex, but nothing happens. The output stays 0.
Does anybody have an explanation?
Thanks for any hint.
It's been a while...
I'm digging into an earlier project in which I started using arrays in order
to generate a sinewave from an external DAC. That was my very first project,
and now I'm trying to make it better.
Before I forget: I'm working on a MAX10M50DAF484C8G, quite an impressive beast.
I'm working on Linux Ubuntu 20.04, and the quartus prime version is also 20.
The latest, I guess.
What I was doing previously was, after generating a 24-bit data file (sine24_4k.hex),
declaring an array reg signed[23:0] signalrom[4095:0];
Basically it worked, but I understood recently that this doesn't use memory blocks
but instead makes everything from logic elements, so I thought it would be better
to shift to existing IP. There is apparenlty what I need in Library -> On Chip Memory
-> ROM: 2port. What I'm thinking is using an array as I did earlier, and interpolate
2 consecutive values to get the accuracy I need.
Ok, after this long preamble, I wrote this.I used only a top module and tried to
instantiate a memory called sig_rom.
There are 3 modes of calculation. (CALC_SWITCH on the first line).
When 0, I simply output the 16-bit upper value of a 24 bit counter. This one works
exactly as intended, I can observe a sawtooth on the scope, and the frequency is
50 MHZ / 65536 = 732Hz.
Then I wanted to verify the addresses for the memory. They should be 12 bit, so I
extract exactly 12 bits from the same 24 bit counter, to get lindex and rindex, the
indices of the 2 values I would like to extract. In order to see the difference of the
2 waves, I shift the rindex value by 1/4 of the array, therefore I expect to get the
exact same frequency as above (732Hz), but one of the 2 sawtooths will be shifted.
Experiment, that's exactly what I observe, therefore I guess lindex and rindex are
right.
Last, I have instantiated the memory, using 2 registers da and db (DA and DB are the
outputs, da and db are the outputs of the memory). So I guess the memory should spit
values addressed by lindex and rindex, but nothing happens. The output stays 0.
Does anybody have an explanation?
Thanks for any hint.
Code:
`define CALC_SWITCH 2
module MemIPTest(
DA,
DB,
error,
max_clk,
clk
);
// Interface variables
output reg [15:0] DA;
output reg [15:0] DB;
output reg error;
output max_clk;
input clk;
// Internal variables
reg[23:0] counter = 0;
reg[11:0] lindex = 0;
reg[11:0] rindex;
reg signed[17:0] da;
reg signed[17:0] db;
reg pll_lock;
reg spi_clk;
// Realtime
// Generate clocks
SysClkPLL system_pll(
.inclk0(clk),
.c0(sys_clk), // Changed sysclock out sys clock
.c1(max_clk),
.c2(spi_clk),
.locked(pll_lock)
);
// Get data from memory
sig_rom signal(
.address_a(lindex),
.address_b(rindex),
.clock(sys_clk),
.q_a(da),
.q_b(db)
);
always@(posedge clk) begin
if(max_clk == 1) begin
counter <= counter+23'h000100; // Add 2^8, therefore counter[23:8] will count 1 by 1 from 0 to 2^16 - 1
if(counter < 23'h001000) begin // Generato output sync pulse for oscilloscope
error <= 1;
end
else begin
error <= 0;
end
// Calculate lindex and rindex for addressig the dual ROM
lindex <= counter[23:12]; // Get a 12 bit addressing value from array
rindex <= lindex + 1024; // Calculate cosine value from 1/4 phase
end
else begin
case(`CALC_SWITCH)
0:
begin
// Check the counter value (works fine on the oscilloscope, observed exactly as it should be).
DA <= counter[23:8]; // Get a 16 bit value for output from counter
DB <= counter[23:8]; // Same on channel B
end
1:
begin
// Check the index values on the oscilloscope. Works fine, values are as expected.
DA <= lindex << 4; // Restore a 16 bit value for observation on the scope
DB <= rindex << 4;
end
2:
begin
// Check the values of the ROM. Does not work. The da and db values are apparently not generated from sig_rom
// I get only 0s.
DA <= da[17:2]; // Make a 16 bit value from 18 bit.
DB <= db[17:2];
end
endcase
end
end
endmodule