-
parus
-
Автор темы
-
Не в сети
-
Новый участник
-
-
Сообщений: 14
-
Спасибо получено: 2
-
-
-
-
-
|
Приветствие.
Хочу сделать такой элемент: входят два провода, выходит регистр из 4 проводов. Импульс по первому входу увеличивает выходное значение на единицу(если значение максимальное, то обнуляет), импульс по второму входу уменьшает значение на 1(если значение 0, то устанавливает в максимальное).
Как я понял, в один регистр нельзя записывать из разных always блоков, соответвеннно такой код не работает: module cnter(input wire plus, input wire minus, output reg[3:0] val);
always @(negedge plus)
val = val +1;
always @(negedge minus)
val = val -1;
endmodule
Такой код module cnter(input wire plus, input wire minus, output reg[3:0] val);
always @(negedge plus or negedge minus) begin
if (!plus) begin
val = val+1;
end else
begin
val = val-1;
end
end
endmodule Работает на minus, а на плюсе зацикливается вместо одного срабатывания.
Ну не делать два счётчика и считать разность? Помогите, пожалуйста, реализовать такой простой модуль.
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
-
nckm
-
-
Не в сети
-
Администрация форума
-
-
Сообщений: 112
-
Спасибо получено: 34
-
-
-
-
-
|
А у вас сигналы minus и plus синхронные или нет? от этого многое зависит. Если не синхронные, то модуль не простой.
Вы рассматриваете два входных импульса, по фронту первого хотите увеличивать счетчик, а по фронту второго уменьшаете.
Это сделать как бы и нельзя, потому что у D-триггера есть только один вход чувствительный к фронту сигнала - это вход С.
На этот вход обычно подают тактовую частоту. Желательно иметь одну тактовую частоту для всего проекта - это сильно упрощает весь проект. Наличие нескольких тактовых частот (когда часть триггеров тактируется одной частотой, а другая часть триггеров тактируется другой частотой - возможно, но очень не просто).
Мне кажется в вашем случае проще всего сделать как-то так. Подключить к проекту некую тактовую частоту. Ее период должен быть гораздо меньше ширины импульсов minus и plus.
1) определять моменты фронтов сигналов minus и plus
reg [2:0]minus_;
always @(posedge clock)
minus_ <= {minus_[1:0],minus}; //shift register
wire minus_edge; assign minus_edge=(minus_[2:1]==2'b01);
reg [2:0]plus_;
always @(posedge clock)
plus_ <= {plus_[1:0],plus}; //shift register
wire plus_edge; assign plus_edge=(plus_[2:1]==2'b01);
2) вот теперь уже используя синхронные сигналы minus_edge и plus_edge мы можем как-то управлять счетчиком
always @(posedge clock)
if(plus_edge)
val <= val+1;
else
if(minus_edge)
val <= val-1;
Я думаю такой метод самый правильный.
Да в verilog можно написать always @(posedge q or posegde b), но это не значит, что триггер может реагировать на фронты двух сигналов. На мой взгляд, это недостаток синтаксиса verilog-а.
При такой записи один сигнал будет использован как ассинхронный сброс R (установка S), а второй как сигнал C у D-триггера.
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
-
parus
-
Автор темы
-
Не в сети
-
Новый участник
-
-
Сообщений: 14
-
Спасибо получено: 2
-
-
-
-
-
|
а always блоков три штуки для понимания или это тоже магия?
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
-
parus
-
Автор темы
-
Не в сети
-
Новый участник
-
-
Сообщений: 14
-
Спасибо получено: 2
-
-
-
-
-
|
Сделал так, работает: module cntr (input wire clock, input wire plus, input wire minus, output reg[3:0] val);
reg[1:0] prev_state;
wire[1:0] inp;
assign inp = {plus, minus};
always @(posedge clock) begin
if (prev_state != inp) begin
if (((prev_state&1)==1)&&((inp&1)!=1))
val = val-1;
if (((prev_state&2)==2)&&((inp&2)!=2))
val = val+1;
prev_state = inp;
end
end
endmodule Регистров кушает, наверное, поменьше...
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
-
SOVA
-
-
Не в сети
-
Давно я тут
-
-
Сообщений: 82
-
Спасибо получено: 5
-
-
-
-
|
В исходном задании изменение состояния счётчика по перепаду плюс и минус входов
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
-
parus
-
Автор темы
-
Не в сети
-
Новый участник
-
-
Сообщений: 14
-
Спасибо получено: 2
-
-
-
-
-
|
Ну требовалось мне именно то, что я написал методом от nckm. А что я не так в задании написал? Это if (((prev_state&1)==1)&&((inp&1)!=1)) так чтоли: if ((prev_state&1)!=(inp&1))
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
-
SEGABOY
-
-
Не в сети
-
Новый участник
-
-
Сообщений: 1
-
Спасибо получено: 0
-
-
|
module cntr (
input plus, minus,
output reg [3:0] val );
wire en = plus | minus;
always @(posedge en) begin
if (plus) val <= val + 1;
else val <= val - 1;
end
endmodule Вот такое решение пойдёт?
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
|
Время создания страницы: 0.252 секунд