Jump to content
Leo

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

Recommended Posts

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

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;

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

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

Share this post


Link to post
Share on other sites

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

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

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

Edited by Vascom

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

Литиевые ХИТы Fanso: устойчивость к высоким температурам

Литиевые ХИТы для широкого круга применений, в том числе в промышленности, соответствуют требованиям современного рынка и способны работать в самых жестких условиях. Основные требования – это длительность хранения и работы, высокая удельная емкость, а также защита от воздействия таких внешних факторов, как температура и влажность. ЛХИТ превосходят по плотности энергии и нормальному напряжению другие элементы автономного питания: 2,9…3,6 В против 1,2…1,5 В

Читать статью...

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

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

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

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

Edited by Vascom

Share this post


Link to post
Share on other sites

Из этого я делаю вывод что 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;

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

Share this post


Link to post
Share on other sites

Плавкие предохранители LittelFuse. Грамотный подбор

Выбор оптимального плавкого предохранителя требует учета многих параметров. Для упрощения выбора оптимального предохранителя и автоматизации расчетов Littelfuse предлагает онлайн-утилиту.

Подробнее...

Должно быть

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

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

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

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

assign sr_out3 = sr[31:24];
Edited by Vascom

Share this post


Link to post
Share on other sites

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

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

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

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

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

Edited by Leo

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

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

Share this post


Link to post
Share on other sites

Я решил попробовать цикл 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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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

sr[0] <= sr_in;

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

assign sr_out = sr[7]; 

на

assign sr_out = sr[7:0];

тоже.

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

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

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

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

Edited by Leo

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

Share this post


Link to post
Share on other sites

Хм, в 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;

Share this post


Link to post
Share on other sites

Я в коде цикла 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];

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

подставил

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

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

Share this post


Link to post
Share on other sites

Вот так:

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;

Share this post


Link to post
Share on other sites

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

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];

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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]);

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Similar Content

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


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

    • By admin
      Показано управление сдвиговым регистром 74HC164 в симуляторе Proteus. На основе этой схемы собраны бегущие огоньки из 16 светодиодов. 
      Бегущие огни.rar
    • By Дмитрий Т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; }
      Вот такая схема

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

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

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