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

Гость Striburn

Вот собственно модуль БИХ-Фильтра. он вполне рабочий сделан под MAX10.

 

Основные требования занимать как можно меньше ячеек и перемножителей.

 

Поэтому старался делать всё на RAMе.

 

 

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

А то я новичок до этого только с С# общался. поэтому кое-какие правила оформления брал оттуда.

 

 

module IIRFilter_ram
(
input logic reset,
input logic inclk,
input logic Din_valid,
input logic[31:0]  InData,

output logic IIRPhase
);

logic [2:0]IIRState;
logic ShiftInValid,OutRamWren,InRamWren;
logic signed[63:0] OutResult,InResult;
logic signed [31:0] ShiftIn,ShiftOut,InRamData,InRamQ,InRomQ,OutRamQ,OutRomQ,OutRamData;
logic [3:0] RAddr,InRamWAddr,OutRamWAddr;
logic [1:0] RDelay;
logic  signed[31:0] MV_TMP;
logic  signed[31:0] MV_Result;
logic [5:0] MVF_SC;


assign IIRPhase=(ShiftOut>MV_Result)?1'b1:1'b0;

always_ff@(posedge inclk,posedge reset)
begin
if(reset)
begin
	OutRamWren<=0;
	InRamWren<=0;
	IIRState<=0;
	OutResult<=0;
	InResult<=0;
	InRamData<=0;
	OutRamData<=0;
	RAddr<=0;
	RDelay<=0;
	OutRamWAddr<=0;
	InRamWAddr<=0;
	ShiftInValid<=1'b0;
	ShiftIn<=0;
	MVF_SC<=0;
	MV_TMP<=0;
	MV_Result<=0;
end
else
begin
	case(IIRState)
	0:
	begin
		if(Din_valid)
		begin
			InRamWAddr<=0;
			InRamData<=InData;
			InRamWren<=1;
			IIRState<=1;
			RAddr<=7;
		end
	end
	1:
	begin
		InRamWren<=0;
		OutRamWren<=0;
		RAddr<=RAddr-1'b1;
		RDelay<=2'b10;
		IIRState<=2;
	end
	2:
	begin
		if(RDelay>0)RDelay<=RDelay-1'b1;
		else IIRState<=3;
	end
	3:
	begin
		InResult<=InResult+InRamQ*InRomQ;
		if(RAddr>0)
		begin
		 OutResult<=OutResult+OutRamQ*OutRomQ;
		 IIRState<=4;
		end
		else
		begin
			IIRState<=5;
		end
	end
	4:
	begin
		OutRamWAddr<=RAddr+1'b1;
		OutRamData<=OutRamQ;
		OutRamWren<=1'b1;
		InRamWAddr<=RAddr+1'b1;
		InRamData<=InRamQ;
		InRamWren<=1'b1;
		IIRState<=1'b1;
	end
	5:
	begin
		OutResult<=OutResult+InResult;
		IIRState<=6;
	end
	6:
	begin
		InRamWAddr<=RAddr+1'b1;
		InRamData<=InRamQ;
		InRamWren<=1'b1;
		OutRamWAddr<=1'b1;
		OutRamData<=OutResult[63:32];
		OutRamWren<=1'b1;
		ShiftInValid<=1'b1;
		ShiftIn<=OutResult[63:32];
		if(MVF_SC<5)
		begin
			MVF_SC<=MVF_SC+1'b1;
			MV_TMP<=MV_TMP+$signed(OutResult[63:32]);
		end
		else
		begin
			MV_TMP<=OutResult[63:32];
			MV_Result<=MV_TMP/6;
			MVF_SC<=0;
		end
		IIRState<=7;
	end
	7:
	begin
		ShiftInValid<=1'b0;
		OutRamWren<=0;
		InRamWren<=0;
		IIRState<=0;
		OutResult<=0;
		InResult<=0;
	end
	endcase
end
end

IIRRAM InRam(
.aclr(reset),
.clock(inclk),
.data(InRamData),
.rdaddress(RAddr),
.wraddress(InRamWAddr),
.wren(InRamWren),
.q(InRamQ)
);
IIRRAM OutRam(
.aclr(reset),
.clock(inclk),
.data(OutRamData),
.rdaddress(RAddr),
.wraddress(OutRamWAddr),
.wren(OutRamWren),
.q(OutRamQ)
);
IIRINROM InRom(
.address({1'b0,RAddr}),
.clock(inclk),
.q(InRomQ)
);
IIROUTROM OutRom(
.address({1'b0,RAddr}),
.clock(inclk),
.q(OutRomQ)
);


IIRMVDELAYSR SRDelay(
.aclr(reset),
.clken(ShiftInValid),
.clock(inclk),
.shiftin(ShiftIn),
.shiftout(ShiftOut),
.taps()
);	

endmodule

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


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

Основные требования занимать как можно меньше ячеек и перемножителей.

Почему именно такой критерий ?

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


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

Гость Striburn
Почему именно такой критерий ?

 

этот модуль часть большого проекта.

на борту плис находятся: 3 PID регулятора, 2 алгоритма герцеля, dds, uart, 4 32-ух битных DAC, и куча систем управления, а в ячеек всего 15000 и 90 перемножителей(9х9).

блоки ADC UFM PLL тоже занимаю какое то место.

 

Так что ячейки и перемножители очень ценный расходный материал а вот памяти там предостаточно(562000 bit)

вот и выкручиваемся как можем

Изменено пользователем Striburn

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


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

Вы на пробелах экономите?

 

Форматирование должно быть таким, чтобы код было удобно и легко читать. Не писать, а читать. Потому что код пишется однажды, а читается многажды. Код без пробелов между служебными символами читать очень тяжело.

 

OutResult<=OutResult+OutRamQ*OutRomQ;

или

OutResult <= OutResult + OutRamQ * OutRomQ;

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


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

Гость Striburn
Вы на пробелах экономите?

 

Форматирование должно быть таким, чтобы код было удобно и легко читать. Не писать, а читать. Потому что код пишется однажды, а читается многажды. Код без пробелов между служебными символами читать очень тяжело.

 

OutResult<=OutResult+OutRamQ*OutRomQ;

или

OutResult <= OutResult + OutRamQ * OutRomQ;

 

Спасибо учту.

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


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

этот модуль часть большого проекта.

на борту плис находятся: 3 PID регулятора, 2 алгоритма герцеля, dds, uart, 4 32-ух битных DAC, и куча систем управления, а в ячеек всего 15000 и 90 перемножителей(9х9).

блоки ADC UFM PLL тоже занимаю какое то место.

 

Так что ячейки и перемножители очень ценный расходный материал а вот памяти там предостаточно(562000 bit)

вот и выкручиваемся как можем

Спасибо. Не будут тут советовать, но мне кажется главное чтобы по нужной частоте развелось. Толку будет 0 от экономии ресурсов, если проект не сможет работать на требуемой частоте.

По поводу читаемости кода, как вам уже сказали поставьте пробелы.

И выравнивайте всё, что можно выровнять например:

Ваш вариант:

begin
    if(reset)
    begin
        OutRamWren<=0;
        InRamWren<=0;
        IIRState<=0;
        OutResult<=0;
        InResult<=0;
        InRamData<=0;
        OutRamData<=0;
        RAddr<=0;
        RDelay<=0;
        OutRamWAddr<=0;
        InRamWAddr<=0;
        ShiftInValid<=1'b0;
        ShiftIn<=0;
        MVF_SC<=0;
        MV_TMP<=0;
        MV_Result<=0;
    end

 

 

Вот так мне кажется лучше :

    if (reset)
    begin
        InRamWAddr   <= 0;
        InRamWren    <= 0;
        InRamData    <= 0;
        InResult     <= 0;

        OutRamWren   <= 0
        OutResult    <= 0;
        OutRamData   <= 0;
        OutRamWAddr  <= 0;

        IIRState     <= 0;

        RAddr        <= 0;
        RDelay       <= 0;

        ShiftInValid <= 1'b0;
        ShiftIn      <= 0;

        MVF_SC       <= 0;
        MV_TMP       <= 0;
        MV_Result    <= 0;
    end

Группируйте сигналы по смыслу. Отделяйте их пустыми строками, так проще читать. И самое главное. Пишите комментарии. Сейчас Вы помните, как это работает. Через пол года забудете.

Изменено пользователем Flip-fl0p

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


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

Гость Striburn
Спасибо. Не будут тут советовать, но мне кажется главное чтобы по нужной частоте развелось. Толку будет 0 от экономии ресурсов, если проект не сможет работать на требуемой частоте.

 

Пока что Тактовая частота 10MHz. а скорость данных вообще меньше 1kHz так что с этим пока проблем не возникает.

 

Кстати если кто нибудь может подсказать где почитать про оптимизацию кода.(конвеерезацию) то очень прошу поделиться.

Изменено пользователем Striburn

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


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

Спасибо учту.
Тогда уж до кучи. Табуляцию на мой скромный взгляд лучше заменить пробелами (двумя или четырьмя); настраивается в редакторе.

Каждый сигнал в объявлении лучше писать на новой строке, чтобы его можно было снабдить комментарием. При этом выравнивая по отступам табуляции.

То есть вместо

logic signed [31:0] ShiftIn,ShiftOut,InRamData,InRamQ,InRomQ,OutRamQ,OutRomQ,OutRamData;
logic [3:0] RAddr,InRamWAddr,OutRamWAddr;

желательно так

logic signed     [31:0] ShiftIn;        //
logic signed     [31:0] ShiftOut;       //
logic signed     [31:0] InRamData;      //
logic signed     [31:0] InRamQ;         //
logic signed     [31:0] InRomQ;         //
logic signed     [31:0] OutRamQ;        //
logic signed     [31:0] OutRomQ;        //
logic signed     [31:0] OutRamData;     //

logic             [3:0] RAddr;          // 
logic             [3:0] InRamWAddr;     //
logic             [3:0] OutRamWAddr;    //

 

Лично мое мнение, CamelCase лучше оставить для PHP или C#.

При проектировании лучше использовать суффиксы, которые будут стандартными для всего процесса разработки.

Ознакомьтесь с известными стандартами (OpenCores Coding Guidelines, Freescale Verilog HDL Coding или другими), возьмите из них лучшее и наиболее близкое собственным представлениям о коде.

 

Группируйте сигналы по смыслу.

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

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


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

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

Каждому своё. Но когда группируется по смыслу можно эту группу сигналов прокооментиировать, описать зачем она нужна. Как работает. Во всяком случае мне так проще работать с кодом. Поскольку я вижу все сигналы управляющие счетчиком, и могу сходу оценить функционал данного счетчика. Зачастую у меня рабочих строк кода может быть 5. А описание зачем эти 5 строк нужны, может занимать 20 строчек. Не вижу в этом ничего зазорного. Пишу то для себя.

 

    ----------------------------------------------------------------------------------------------
    -- Счетчик, считающий сколько бит принято 
    -- Описание
    -- Описание 
    -- Описание
    SIGNAL COUNTER_BIT_RX       : INTEGER RANGE 0 TO SDB-1 :=  0;      -- Счетчик количества принятых битов данных
    SIGNAL COUNTER_BIT_ENA      : STD_LOGIC := '0';                     -- Сигнал разрешения работы счетчика
    SIGNAL COUNTER_BIT_CLR      : STD_LOGIC := '0';                     -- Сигнал синхронного сброса счётчика
    SIGNAL COUNTER_BIT_SLD      : STD_LOGIC := '0';                     -- Сигнал синхронной загрузски данных в счетчик
    SIGNAL COUNTER_BIT_SLD_DATA : STD_LOGIC_VECTOR(7 DOWNTO 0);         -- Данные загружаемые в счетчик

Изменено пользователем Flip-fl0p

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


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

Гость Striburn
Лично мое мнение, CamelCase лучше оставить для PHP или C#.

При проектировании лучше использовать суффиксы, которые будут стандартными для всего процесса разработки.

Ознакомьтесь с известными стандартами (OpenCores Coding Guidelines, Freescale Verilog HDL Coding или другими), возьмите из них лучшее и наиболее близкое собственным представлениям о коде.

 

Да возможно. спасибо за ссылки ознакомлюсь)

 

 

Тогда уж до кучи. Табуляцию на мой скромный взгляд лучше заменить пробелами (двумя или четырьмя); настраивается в редакторе.

 

А можно по подробнее где и как настраивать?

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


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

Согласен. Поэтому делаю так же.

Еще вспомнил правило, которого придерживаюсь. Хотя сегодня многие считают это атавизмом.

Стараюсь не превышать 80 символов по длине строки. Отсюда вытекает несколько удобств при чтении кода и работе с ним.

 

А можно по подробнее где и как настраивать?

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

 

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


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

Гость Striburn
Это зависит от редактора, в котором работаете. Но сегодня в подавляющем большинстве редакторов табуляцию можно настроить. Поищите в настройках.

 

я Quartus использую, а для *.mif или *.sdc Notepad++.

и к сожалению в них нет ни авто пробелов ни автотабуляции. А я так привык к этим мелочам(в MS VS 2015)

Изменено пользователем Striburn

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


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

logic это случаем не из SystemVerilog? быть может некоторые синтезаторы не скушают

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


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

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

А то я новичок до этого только с С# общался. поэтому кое-какие правила оформления брал оттуда.

Если хотите, то могу по скайпу голосом. примерно 20 мин займет...

Или ищите у меня на сайте...

 

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


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

Гость Striburn
logic это случаем не из SystemVerilog? быть может некоторые синтезаторы не скушают

 

да это он. Но Quartus справляется. В железе всё работает.

 

Если хотите, то могу по скайпу голосом. примерно 20 мин займет...

Или ищите у меня на сайте...

 

 

К сожалению на работе никак.

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


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

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

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

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

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

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

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

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

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

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