Перейти к содержанию
    

Двухпортовая память

В процессе размышлений на проектом возник вопрос.

Возможно ли описать на чем-либо (чтобы Quartus понял и разместил в RAM) реализацию специфичного массива памяти.

Память двухпортовая, но адресация ячеек на портах отличается друг от друга.

Если представить массив ячеек в виде матрицы, то

первый порт сопоставляет адресу номер строки матрицы, а номеру бита входа данных - номер столбца матрицы;

второй порт - наооборот, адресу сопоставляет номер столбца, а номеру бита - номер строки.

Иными словами получается транспонирование массива данных при чтении-записи по разным портам. Вообще реально? Ведь если транспонировать последовательно, то задача занимает много времени.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В процессе размышлений на проектом возник вопрос.

Возможно ли описать на чем-либо (чтобы Quartus понял и разместил в RAM) реализацию специфичного массива памяти.

Память двухпортовая, но адресация ячеек на портах отличается друг от друга.

Если представить массив ячеек в виде матрицы, то

первый порт сопоставляет адресу номер строки матрицы, а номеру бита входа данных - номер столбца матрицы;

второй порт - наооборот, адресу сопоставляет номер столбца, а номеру бита - номер строки.

Иными словами получается транспонирование массива данных при чтении-записи по разным портам. Вообще реально? Ведь если транспонировать последовательно, то задача занимает много времени.

Quartus "поймёт" подобное описание и в памяти ...не разместит :biggrin:

посмотрите на устройство(архитектуру) памяти. ;)

а вообще реально, но в не памяти размещать, а в триггерах

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пардон, может я не совсем понял...

Но может шину адреса представить как

2 шины (столбец, сторока), а со стороны чтения сделать соответствующий

декодер по адресной шине.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возможно ли описать на чем-либо (чтобы Quartus понял и разместил в RAM) реализацию специфичного массива памяти.

Память двухпортовая, но адресация ячеек на портах отличается друг от друга.

///////////////////////////

если так к памяти подойти, то можно. И адресация на портах отличается друг от друга:

 

parameter size_i = 32;

parameter size_j = 4;

 

output [3:0] q;

input [3:0] d;

 

reg [3:0] mem [size_j*size_i-1:0];

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Похоже меня не поняли :( , попробую конкретизировать.

Задача записать в память данные с нескольких входов в последовательном коде (вывод данных у каналов синхронизирован) и затем за одно чтение из памяти получать данные одного канала в параллельном коде. Т.е. нужно сразу писать в память словами, состоящими из одного n-ного бита всех каналов и читать тоже словом, но уже все n-бит одного канала.

Или по аналогии - писать слово "по горизонтали", а читать - "по вертикали".

 

Получается реализовать на нескольких сдвиговых регистрах с мультиплексором, но уж очень ресурсоемкость большая по логическим ячейкам. А память вообще не используется...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если я не ошибаюсь, то блоки памяти, например в Cyclon I, могут работать в режиме двух-портового ОЗУ с индивидуальной настройкой каждого порта. Т.е. на запись это например 512x8, а на чтение 128x32. В этом случае, за одну операцию чтения можно прочитать 4 последовательных бита всех 8 каналов. Если этого мало, то можно на запись делать например 2Kх2, а на чтение 128x32 и параллельно работать с несколькими такими блоками.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Похоже меня не поняли :( , попробую конкретизировать.

Задача записать в память данные с нескольких входов в последовательном коде (вывод данных у каналов синхронизирован) и затем за одно чтение из памяти получать данные одного канала в параллельном коде. Т.е. нужно сразу писать в память словами, состоящими из одного n-ного бита всех каналов и читать тоже словом, но уже все n-бит одного канала.

Или по аналогии - писать слово "по горизонтали", а читать - "по вертикали".

 

Получается реализовать на нескольких сдвиговых регистрах с мультиплексором, но уж очень ресурсоемкость большая по логическим ячейкам. А память вообще не используется...

да запустите вы megawizard :)

вот что получается

// megafunction wizard: %RAM: 2-PORT%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altsyncram 

// ============================================================
// File Name: tt.v
// Megafunction Name(s):
//             altsyncram
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 6.0 Build 202 06/20/2006 SP 1.18 SJ Full Version
// ************************************************************

module tt (
    clock,
    data,
    rdaddress,
    wraddress,
    wren,
    q);

    input      clock;
    input    [0:0]  data;
    input    [1:0]  rdaddress;
    input    [4:0]  wraddress;
    input      wren;
    output    [7:0]  q;

    wire [7:0] sub_wire0;
    wire [7:0] q = sub_wire0[7:0];

    altsyncram    altsyncram_component (
                .wren_a (wren),
                .clock0 (clock),
                .address_a (wraddress),
                .address_b (rdaddress),
                .data_a (data),
                .q_b (sub_wire0),
                .aclr0 (1'b0),
                .aclr1 (1'b0),
                .addressstall_a (1'b0),
                .addressstall_b (1'b0),
                .byteena_a (1'b1),
                .byteena_b (1'b1),
                .clock1 (1'b1),
                .clocken0 (1'b1),
                .clocken1 (1'b1),
                .data_b ({8{1'b1}}),
                .q_a (),
                .rden_b (1'b1),
                .wren_b (1'b0));
    defparam
        altsyncram_component.address_reg_b = "CLOCK0",
        altsyncram_component.clock_enable_input_a = "BYPASS",
        altsyncram_component.clock_enable_input_b = "BYPASS",
        altsyncram_component.clock_enable_output_b = "BYPASS",
        altsyncram_component.intended_device_family = "Cyclone II",
        altsyncram_component.lpm_type = "altsyncram",
        altsyncram_component.numwords_a = 32,
        altsyncram_component.numwords_b = 4,
        altsyncram_component.operation_mode = "DUAL_PORT",
        altsyncram_component.outdata_aclr_b = "NONE",
        altsyncram_component.outdata_reg_b = "UNREGISTERED",
        altsyncram_component.power_up_uninitialized = "FALSE",
        altsyncram_component.ram_block_type = "M4K",
        altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE",
        altsyncram_component.widthad_a = 5,
        altsyncram_component.widthad_b = 2,
        altsyncram_component.width_a = 1,
        altsyncram_component.width_b = 8,
        altsyncram_component.width_byteena_a = 1;


endmodule

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Задача записать в память данные с нескольких входов в последовательном коде (вывод данных у каналов синхронизирован) и затем за одно чтение из памяти получать данные одного канала в параллельном коде. Т.е. нужно сразу писать в память словами, состоящими из одного n-ного бита всех каналов и читать тоже словом, но уже все n-бит одного канала.

Или по аналогии - писать слово "по горизонтали", а читать - "по вертикали".

////////////////////////////////////////////////

Записать наверно можно, а считать наверно нельзя. Наверно надо условия поменять.

Есть массив памяти, последовательно пишем в нее 0 отсчеты каждого канала. 1 отсчеты каждого канала

И последовательно считываем 0 отсчет, 1 отсчет ..... первого канала, 0,1,...... второго канала. и т.д.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если у вас N каналов по К бит, и вы хотите единовременно записать К-битное слово, и вычитать вы его тоже хотите за одну операцию, то читать вам придется слово шириной N*К.

Тогда по маске сможете выковырять оттуда нужные данные (каждый N-ый бит).

 

Еще вам был предложен вариант сделать на N блоках памяти. Каждый канал пишет в свой блок, а читаете вы из нужного вам блока.

 

Либо на триггерах думать, как с самого начала вам сказал Postoroniy_V.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

еще вариант задрать тактовую в К раз, и спокойно не торопясь разгребать каналы последововательно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

да запустите вы megawizard :)

 

Ах хороша идея была. Проверил, вот что пишет квартус по этому поводу

 

Error: Assertion error: Can't implement dual-port RAM for ACEX1K device family from altsyncram megafunction because mixed widths for read and write ports are not supported in altdpram megafunction

 

Похоже не судьба сделать это на ACEX. Жаль, придется на защелках...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...