Leo

Не Работает Сдвиговый Регистр В Верилог

145 сообщений в этой теме

Leo    3

Хотел спросить насчет сдвигового регистра я взял на сайте альтеры пример но он что то не заработал

www.altera.com/support/examples/verilog/verilog.html

www.altera.com/support/examples/verilog/ver-1x64-shift-reg.html

module shift_1x64 (clk,

shift,

sr_in,

sr_out,

);

input clk, shift;

input sr_in;

output sr_out;

reg [63:0] sr;

always@(posedge clk)

begin

if (shift == 1'b1)

begin

sr[63:1] <= sr[62:0];

sr[0] <= sr_in;

end

end

assign sr_out = sr[63];

endmodule

Тут есть какие то тонкости он не заполняет данными регистр и не передает данные на вывод и данные он должен выводить сразу как они обновились или в конце когда полностью заполнен регистр [63:0] sr;

Пример простой но почему то не работает. Хотя что то похожее видел в примерах у других.

Запускал с простым тест бэнчем данные приходят но в регистр не записываются.

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


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

Всё тут работает. Данные на выходе появятся после заполнения регистра sr[63:0].

Видишь это assign sr_out = sr[63]; - на выход идёт последний бит. А тут sr[0] <= sr_in; - заполнение регистра начинается с первого бита.

Покажи свой тестбенч, возможно в нём у тебя ошибка. Может ты клок не подал или shift не поставил в 1.

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

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


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

Привел всё сразу со всеми изменениями которые внес. Что не так не понятно.

module counter (

shift,

clk,

sr_in,

sr_out3

);

input shift,clk;

input wire [7:0]sr_in;

output [7:0] sr_out3;

reg [31:0]sr;

always @ (posedge clk)

begin

if (shift == 1'b1)

begin

sr[31:1] <= sr[30:0];

sr[0] <= sr_in;

$display("%d",sr[n]);

end

end

assign sr_out3 = sr[31];

initial

$monitor($stime,, shift,, clk,,, sr_out3, sr_in );

endmodule

module test_counter;

reg shift,clk;

reg [7:0]sr_in;

wire [7:0] df1,df4;

counter counter_inst(shift,clk,sr_in,

df1,df4);

always

#10 clk = ~clk;

initial

begin

clk = 0;

shift = 0;

sr_in=8'h00;

#10;

@(posedge clk)

#0

begin

shift = 1;

sr_in=8'h55;

end

@(posedge clk)

#0

begin

shift = 0;

sr_in=8'h00;

end

#10;

@(posedge clk)

#0

begin

shift = 1;

sr_in=8'h56;

end

@(posedge clk)

#0

begin

shift = 0;

sr_in=8'h00;

end

#10;

@(posedge clk)

#0

begin

shift = 1;

sr_in=8'h53;

end

@(posedge clk)

#0

begin

shift = 0;

sr_in=8'h00;

end

#10;

@(posedge clk)

#0

begin

shift = 1;

sr_in=8'h51;

end

@(posedge clk)

#0

begin

shift = 0;

sr_in=8'h00;

end

end

initial

begin

#200 $finish;

end

initial

begin

$dumpfile("out.vcd");

$dumpvars(0,test_counter);

end

endmodule

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


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

Впервые на русском языке! Работаем с микроконтроллерами STM32F7(на основе STM32F7 Online Training)

Цикл материалов на основе STM32F7 Online Training от компании STMicroelectronics. Описаны функциональные блоки и инструменты разработки для семейства микроконтроллеров STM32F7, охватывающие тематику системной периферии, памяти, безопасности, аналоговой периферии, цифровой периферии, таймеров, экосистемы.

Подробнее>>

Vascom    660

Внеси это в тег "Код" пожалуйста.

Ну и сразу видны ошибки у тебя:

input wire [7:0]sr_in;
sr[0] <= sr_in;

Вход у тебя восьмибитный, но в регистр ты кладёшь только один бит, причём непонятно какой (нулевой наверное).

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

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


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

Из этого я делаю вывод что sr[7] и смещение sr[31:1] <= sr[30:0]; тоже переделываю

if (shift == 1'b1)

begin

sr[31:1] <= sr[30:0];

sr[0] <= sr_in;

на

if (shift == 1'b1)

begin

sr[31:1] <= sr[23:0];

sr[7] <= sr_in;

Изменение есть но результата нет.

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


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

Должно быть

sr[31:8] <= sr[23:0];
sr[7:0] <= sr_in;

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

И на выход у тебя идёт лишь один старший бит assign sr_out3 = sr[31];

Если ты хочешь все 8 бит на выходе иметь, то сделай

assign sr_out3 = sr[31:24];
Изменено пользователем Vascom

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


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

Как хорошо не много просветлело и заработало. Но мне попался ещё один сдвиговый регистр этот заработал почти сразу

sr <= { sr[31:0],sr_in };

но не очень ясно если разница с предыдущим вариантом

sr[31:8] <= sr[23:0]; sr[7:0] <= sr_in;

или это разнообразие в написании. Ещё хотел спросить насчет For вроде он не используется в коде при описании для микросхемы а только в тест бэнче?

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

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


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

Это разнообразие в описании.

Причём вариант

sr <= { sr[31:0],sr_in };

написан неграмотно. Слева у нас 32-рязрядный регистр sr, а справа ему присваивается уже 40-разрядное значение. Конечно компилятор умный, он отбросит старшие 8 разрядов, но вдруг нет? Так что если уж писать в одну строку, то так:

sr <= { sr[23:0],sr_in };

В общем все неочевидности лучше сразу убирать. Так код и читается лучше, и поддерживается и работает .

For вполне можно использовать и для описания микросхемы. Иногда это позволяет сделать код более компактным.

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


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

Я решил попробовать цикл For

module counter (

shift,

clk,

sr_in,

sr_out,

sr_out1,

sr_out2,

sr_out3,

sr_out4

);

input shift,clk;

input wire [7:0]sr_in;

output [7:0]sr_out,sr_out1,sr_out2,sr_out3,sr_out4;

reg [7:0] sr [31:0];

integer n;

always @ (posedge clk)

if (shift == 1'b1)

begin

for (n = 31; n>0; n = n-1)

begin

sr[n] <= sr[n-1];

$display("%d",sr[n]);

end

sr[0] <= sr_in;

end

assign sr_out = sr[7];

assign sr_out1 = sr[15];

assign sr_out2 = sr[23];

assign sr_out3 = sr[31];

initial

$monitor($stime,, shift,, clk,,,sr_out, sr_in );

endmodule

[code]

module shift_8x64_taps (clk,

shift,

sr_in,

sr_out,

sr_tap_one,

sr_tap_two,

sr_tap_three,

);

input clk, shift;

input [7:0] sr_in;

output [7:0] sr_tap_one, sr_tap_two, sr_tap_three, sr_out;

reg [7:0] sr [63:0];

integer n;

always@(posedge clk)

begin

if (shift == 1'b1)

begin

for (n = 63; n>0; n = n-1)

begin

sr[n] <= sr[n-1];

end

sr[0] <= sr_in;

end

end

assign sr_tap_one = sr[15];

assign sr_tap_two = sr[31];

assign sr_tap_three = sr[47];

assign sr_out = sr[63];

endmodule

Но проблема таже не загружаются данные хотя пример обсолютно такой же.Только значения поменял.

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


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

Ты упорно пытаешься выходным многоразрядным шинами присваивать однобитовые значения.

Строй эпюры всех сигналов, и у видишь где у тебя проблемы.

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


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

При построении эпюр выходит что не загружается регистр.

sr[0] <= sr_in;

А изменить sr[0] на sr[7:0] не удается компилятор ругается. И

assign sr_out = sr[7]; 

на

assign sr_out = sr[7:0];

тоже.

Ведь при таком написании он заносит в регистр 8 бит.

Но проблема помойму в цикле For где n должно быть типа регистра я запутался.

Пример который я взял тоже работает с регистром а не содним сигналом?

И что значит построить все эпюры загрузка не идет и дальше нету результатов.

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

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


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

Так sr_out у тебя же и есть 8 бит.

А вот за масситвы ты рано взялся. Это reg [7:0] sr [31:0]; тут совершенно ни к чему.

Ты всё слишком усложнил, не разобравшись с простейшим.

Выясняй почему регистр sr[0] не загружается. И не используй конструкции for без необходимости. Как видишь, это тут всё лишь усложняет.

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


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

Можно не много пояснений простой сдвиговый регистр у меня получился который был в самом начале он заполняется и выводит результат который указан assign sr_out = sr[7:0]; через него проходят все предидущие и в конце в нем остается что

нужно sr[7:0]. Я взял не удачный пример но он приводился как продолжение сдвигового регистра разделяя его на части регистр

с отводами наверное для более правельного чтения куска регистра.Хотя что то не так. Я хотел на примере понять как работает цикл For.Так много операторов что не понятно какой правельно использовать.

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


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

Хм, в Verilog совсем немного операторов. for работает так же как и везде.

А отвод из регистра сделать очень просто.

Допустим сдвиговый регистр наш по 8 бит сдвигает

sr[31:8] <= sr[23:0];
sr[7:0] <= sr_in;

Тогда отводы будут такими

assign ssr_out = sr[31:24];
assign ssr_out_1 = sr[23:16];
assign ssr_out_2 = sr[15:8];
assign ssr_out_3 = sr[7:0];

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

output [7:0] sr_out;
output [7:0] sr_out1;
output [7:0] sr_out2;
output [7:0] sr_out3;

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


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

Я в коде цикла For удалил массив. Симулятор показывает что регистр заполняется побитно приходящими данными но только первые 8 бит а в эпюрах регистр так и не заполняется.Он не правельно читает sr_in врядли наверное проблема sr[n] <= sr[n-1];

он же отвечает за заполнение?

reg [31:0]sr;
integer n;
always @ (posedge clk)

if (shift == 1'b1)
	 begin

for (n = 31; n>0; n = n-1)
begin

sr[n] <= sr[n-1];

$display("%d",sr[n]);
end
sr[7:0] <= sr_in;
end
			 assign sr_out = sr[7:0];
			 assign sr_out1 = sr[15:8];
			 assign sr_out2 = sr[23:16];
			 assign sr_out3 = sr[31:24];

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


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

Конечно. Раз у тебя 8 бит на входе, то и регистр надо заполнять по 8 бит, а не по одному биту. Переделай.

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


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

Не знаю как переделать цикл For вместо

sr[n] <= sr[n-1];

подставил

sr[31:8] <= sr[23:0];

но For тогда зачем как должно быть правельно.

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


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

Вот так:

for (n = 1; n<4; n = n+1)
begin																										
  sr[(n+1)*8-1:n*8] <= sr[n*8-1:(n-1)*8];														
end
sr[7:0] <= sr_in;

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


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

Вот это конструкция "больше вопросов чем ответов" Что то в твоей конструкции ему не понравилось и отладчик ругается.

reg [31:0]sr;
integer n;
always @ (posedge clk)
if (shift == 1'b1)
			 begin
for (n = 1; n<4; n = n+1)
begin
sr[(n+1)*8-1:n*8] <= sr[n*8-1:(n-1)*8]; 
$display("%d",sr[n]);
end
sr[7:0] <= sr_in;
end
							 assign sr_out = sr[7:0];
							 assign sr_out1 = sr[15:8];
							 assign sr_out2 = sr[23:16];
							 assign sr_out3 = sr[31:24];

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


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

Ну а где ругань-то? И неправильно ты выводишь $display("%d",sr[n]);

Покажи что он пишет.

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


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

ppp2.v:35: error: Part select expressions must be constant.

ppp2.v:35: : This lsb expression violates the rule: (n)*('sd8)

ppp2.v:35: error: Part select expressions must be constant.

ppp2.v:35: : This msb expression violates the rule: (((n)+('sd1))*('sd8))-('sd1)

ppp2.v:35: error: Part select expressions must be constant.

ppp2.v:35: : This lsb expression violates the rule: ((n)-('sd1))*('sd8)

ppp2.v:35: error: Part select expressions must be constant.

ppp2.v:35: : This msb expression violates the rule: ((n)*('sd8))-('sd1)

ppp2.v:35: error: Part select expressions must be constant.

ppp2.v:35: : This lsb expression violates the rule: ((n)-('sd1))*('sd8)

ppp2.v:35: error: Part select expressions must be constant.

ppp2.v:35: : This msb expression violates the rule: ((n)*('sd8))-('sd1)

6 error(s) during elaboration.

А как правельно?

$display("%d",sr[n]);

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


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

ОК, значит нельзя такое через цикл for провернуть.

Забил бы ты на эти циклы. Это же не Си, а Верилог, тут и без циклов всё отлично и понятно делается.

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


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

Логично просто хотел понять что за код для работы с регистрами через For на сайте Альтера и при этом оказался не рабочий ведь заполнения регистра у меня тоже не получалось а оказалось всё просто. Есть ещё вопрос когда регистров много. С начала я заполняю один большой регистр разбиваю на меньшие а потом мне их надо сравнить все с определенными данными все сравнения пишутся в ручную для каждого малого регистра или они выводятся на оператор case.

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


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

Не совсем понятна твоя формулировка.

Если хочешь, чтобы они одновременно сравнивались - то конечно каждый описываешь.

А если хочешь по очереди - можешь через оператор case.

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

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


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

О да меня параллелизм интересует почему и пробую понять. Просто когда их много штук 80 каждому пишется вывод assign sr_out = sr[7:0]; и для каждого пишутся сравнения которые нужны или в цикле возможно.

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


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

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Похожие публикации

    • Автор: Scinar
      Привет всем. Хочу собрать калькулятор на atmega 328p. Но не как не могу запустить LCD TIC55, основанный на сдвиговом регистре с чипом ML1001. Никогда не связывался с подобным дисплеем. Понравился очень экономичным потреблением тока и экономным количеством выводов управления - всего 3. Проблема в тактирование, как написать программу для вывода хотя б одного символа, документации мало нашел, так же есть библиотека для atmel studio 5, сам пользуюсь 7. Библиотку переделал под 7 но дисплей так ничего и не вывел. Подскажите как правильно написать программу, язык значения не имеет хоть assembler или С. Мне надо что б дисплей вывел хоть один символ корректно, дальше разберусь


      TIC55 Display Module.pdf
    • Автор: Корлет
      Надо составить схему регистра на триггерах, выполняющую сложение по модулю два. Складывается два двоичных числа: то, которое хранится на триггере, и то, которое подаётся на вход. С конъюнкцией получилось легко, а вот xor никак не могу придумать. Если кто знает, дайте, пожалуйста, схему или хотя бы расскажите на словах, что где.

    • Автор: admin
      Показано управление сдвиговым регистром 74HC164 в симуляторе Proteus. На основе этой схемы собраны бегущие огоньки из 16 светодиодов. 
      Бегущие огни.rar
    • Автор: Дмитрий Т87
      Здравствуйте. Прошу помощи в теме статитическая индикация 6 разрядного 7ми сегментного индикатора по 2м проводам Data и Clock.
      Есть такой код для 3х разрядного индикатора в CVavr Си
      Хочу закидывать данные в каждый разряд отдельно, и выводить эти функции в прерываниях avr микроконтроллера.

      // cd4094 control example by kalobyte.com 2009 #include <avr/io.h> #define F_CPU 1000000UL #include <util/delay.h> #define REG_PORT PORTB #define REG_DDR DDRB #define REG_PIN_DATA 3 #define REG_PIN_CLK 4 //--- #define REG_DATA_ON REG_PORT|=1<<REG_PIN_DATA; #define REG_DATA_OFF REG_PORT&=~(1<<REG_PIN_DATA); #define REG_CLK {REG_PORT|=1<<REG_PIN_CLK;REG_PORT&=~(1<<REG_PIN_CLK);} unsigned char digs[10]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; // katode // unsigned char digs[10]={0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; //anode void cd4094_init(void){ char i=0; while(i!=24){ REG_CLK i++; } } void cd4094(int dig){ char i,tmp,j; //dig = 123; int div[4]; div[1] = digs[dig%10]; dig = dig/10; div[2] = digs[dig%10]; div[3] = digs[dig/10]; for(j=3;j>0;j--){ tmp = div[j]; for(i=8;i>0;i--){ if(tmp & 0x80){ REG_DATA_ON } else {REG_DATA_OFF} tmp <<=1; REG_CLK } } } int main(void){ int i=1; REG_DDR = (1<<REG_PIN_DATA)|(1<<REG_PIN_CLK); REG_PORT = (0<<REG_PIN_DATA)|(0<<REG_PIN_CLK); cd4094_init(); //cd4094(2); while(i<999){ _delay_ms(1000); cd4094(i); i++; } return 0; }
      Вот такая схема

    • Автор: peanutwolf
      Добрый день!
      Прошу помощи.
      Имеется клемма, на вход которой поочередно необходимо подавать 12В. Подскажите, как это сделать с использованием сдвигового регистра.
      Пробовал делать через транзисторный ключ, но у меня его ни как не получается запереть при подаче 5 вольт на базу.
      Здесь я подаю 0 на базу, на коллекторе 12В:

      Здесь я подаю 1 на базу, напряжение на коллекторе так же 12В:

      Буду так же очень благодарен, если кто нибудь подскажет вариант решения без использования транзистора.
  • Сообщения

    • FMC - это что ли шина к внешней памяти, то есть дисплей как память подключен? (интересно просто) ну да треть секунды на отрисовку многовато, но если посчитать: 800х480 х 2 (байта на пиксель) = 768000  768000 / 4 (транзакция записи- скажем)= 192000 операций на экран  192000 / 80 000 (операций в мили секунду) = 2.4 милисекунд Это если частота проца 80МГц и и операция чтения памяти-записи в видео-память один такт! У вас получается она = 370 / 2.4 = 154 такта - многовато, должно быть точно не больше 20-ти.
    • Эт понятно. С9 увеличивать потихоньку?
    • По поводу SDRAM.
      Вот, что обещают ST :
      При разрешении в 800х600 можно спокойно получить 60 Гц. Т.е. проц спокойно сможет работать с SDRAM на 40 МГц. А при FHD - так вообще 74 МГц.
      Эта таблица, конечно, для LTDC и DMA2D, но всё-таки...
    • Может ты и прав... со временем улеглось бы. Но йо.......твоючортавдушусердцумать!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! В случае телефонного звонка я обязан выполнить обряд автоэкзорцизма (вылезти всем телом из какого-нибудь электронного сундука с мочалкой проводов, плат и высоковольльтных контактов), объяснить где я нахожусь (держись, сука, за стул - правда тебя шокирует: среда, 9:40 утра, а я на работе. Парадоксально, не правда-ли), потом объяснить почему так долго не брал телефон и еще пол-часа доказывать как сильно я люблю свою Бусичку. А потом залезть обратно и, после всей этой головомойки, вспомнить че я там делал и на чем я, млять, остановился, обшарив кучу плат и запомнив кучу режимов и алгоритмов Мож я в натуре конченный психопат, но более чем на 8 месяцев такой "любви" меня не хватало