Verilog 공부
HDLBits (Verilog Language - Procedures) - Verilog 문제 풀이 1-4
Opens
2024. 9. 6. 12:43
https://github.com/dlwotjr/HDL_Bits
GitHub - dlwotjr/HDL_Bits
Contribute to dlwotjr/HDL_Bits development by creating an account on GitHub.
github.com
https://hdlbits.01xz.net/wiki/Main_Page
HDLBits
HDLBits — Verilog Practice HDLBits is a collection of small circuit design exercises for practicing digital hardware design using Verilog Hardware Description Language (HDL). Earlier problems follow a tutorial style, while later problems will increasingl
hdlbits.01xz.net
- Verilog의 조건문에는 if, else, repeat, while, for, case가 있음
begin / end
- c의 함수에서 {}와 같은 의미
- 대부분 initial always forever if-else와 함께 사용
initial
- 최초의 시작시점
- 시뮬레이션의 시작 시점 - 0ns
always
- @ : sensitive list 이후 나오는 변수들이 변화에 따라 움직임
- 보통 always사용해 플립플롭을 모델링함(상승에지 posegde/ 하강 에지-negedge)
fork - join
- 개별 process의 생성 및 수행
- join문에서 모든 process가 종료되면 서브루틴이 종료됨
- process를 parallel하게 수행
if-else
- case의 표현식에 전체 bit를 사용할 수 있는게 아니면 if-else쓰는게 좋음
example : 4:1 MUX
always @(*)
begin
if(sel == 'h0)
out = a;
else if(sel == 'h1)
out = b;
else if(sel == 'h2)
out = c;
else if(sel == 'h3)
out = d;
end
case statement
- 초기값이나 defualt없으면 회로 합성시에 latch 발생시킴
example : 4:1 MUX
always @(*)
begin
case(sel)
0 : out = a;
1 : out = b;
2 : out = c;
3 : out = d;
default : out = 'bx;
endcase
end
Ternary Operator
- 삼항연산자 - 근데 연쇄도 가능함
result = (expression) ? expression_a : expression_b;
example : 4:1 MUX
assign out = (sel == 0) ? a :
(sel == 1) ? b :
(sel == 2) ? c : d;
for statement
for( init_expression; cond_expression; loop_expression ) begin
statements;
end
while statement
while ( cond_expression ) begin
statements;
end
문제 : always Blocks(combinational)
- combinational always Blocks == assign statements (두개로 표현가능)
// synthesis verilog_input_version verilog_2001
module top_module(
input a,
input b,
output wire out_assign,
output reg out_alwaysblock
);
assign out_assign = a & b;
always @(*) out_alwaysblock = a & b;
endmodule
문제 : Always Block(clocked)
verilog 의 할당 3가지 방식
- 연속 할당(Continuous Assignment) / 차단 할당(Blocking Assignment) / 비차단 할당(Non-Blocking Assignment)
- Continuous Assignment
- assign a= b+c;
- 조합회로에서 사용
- assign이 몇개든 순서에 상관없이 할당됨
- Blocking Assignment
- always @($*$) a= b+c;
- 이걸 할당하는 동안 밑에 있는 것은 순서를 기다리며 할당이 되지 않음
- 내부 값이 바뀌면 순차적으로 할당을 함
- Non-Blocking Assignment
- always @(posedge clk) a<=b+c;
- clk의 rising edge에서만 assign됨
- <= 로 할당함
// synthesis verilog_input_version verilog_2001
module top_module(
input clk,
input a,
input b,
output wire out_assign,
output reg out_always_comb,
output reg out_always_ff );
assign out_assign = a ^ b;
always @(*) out_always_comb = a ^b;
always @(posedge clk) out_always_ff <= a^b;
endmodule
문제 : if statement
// synthesis verilog_input_version verilog_2001
module top_module(
input a,
input b,
input sel_b1,
input sel_b2,
output wire out_assign,
output reg out_always );
assign out_assign = sel_b1&sel_b2 ? b : a;
always @(*) begin
if(sel_b1==1 && sel_b2 ==1)
out_always = b;
else
out_always = a;
end
endmodule
문제 : if statement latches
- "출력을 변경하지 않고 유지"라는 동작은 상태 기억이 필요 -> latch 생성
- else 항상 쓸 것 of default값
// synthesis verilog_input_version verilog_2001
module top_module (
input cpu_overheated,
output reg shut_off_computer,
input arrived,
input gas_tank_empty,
output reg keep_driving ); //
always @(*) begin
if (cpu_overheated)
shut_off_computer = 1;
else
shut_off_computer = 0;
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty;
else
keep_driving = ~arrived;
end
endmodule
문제 : Case statement
module top_module (
input [2:0] sel,
input [3:0] data0,
input [3:0] data1,
input [3:0] data2,
input [3:0] data3,
input [3:0] data4,
input [3:0] data5,
output reg [3:0] out );//
always@(*)
begin // This is a combinational circuit
case(sel)
3'b000 : out = data0;
3'b001 : out = data1;
3'b010 : out = data2;
3'b011 : out = data3;
3'b100 : out = data4;
3'b101 : out = data5;
default : out = 3'b000;
endcase
end
endmodule
문제 : Priority Encoder
- 나는 Don't care term을 이용해 문제를 품
- casez라는 것을 이용하면 가능
module top_module (
input [3:0] in,
output reg [1:0] pos );
always@(*)begin
casez(in)
4'b???1 : pos = 2'd0;
4'b??10 : pos = 2'd1;
4'b?100 : pos = 2'd2;
4'b1000 : pos = 2'd3;
default pos = 2'd0;
endcase
end
endmodule
- 문제에서 제시한 답안
module top_module (
input [3:0] in,
output reg [1:0] pos
);
always @(*) begin // Combinational always block
case (in)
4'h0: pos = 2'h0; // I like hexadecimal because it saves typing.
4'h1: pos = 2'h0;
4'h2: pos = 2'h1;
4'h3: pos = 2'h0;
4'h4: pos = 2'h2;
4'h5: pos = 2'h0;
4'h6: pos = 2'h1;
4'h7: pos = 2'h0;
4'h8: pos = 2'h3;
4'h9: pos = 2'h0;
4'ha: pos = 2'h1;
4'hb: pos = 2'h0;
4'hc: pos = 2'h2;
4'hd: pos = 2'h0;
4'he: pos = 2'h1;
4'hf: pos = 2'h0;
default: pos = 2'b0; // Default case is not strictly necessary because all 16 combinations are covered.
endcase
end
// There is an easier way to code this. See the next problem (always_casez).
endmodule
- if문으로 푼다면?
module priority_encoder_4bit (
input [3:0] in, // 4-bit input
output reg [1:0] out // 2-bit output
);
always @(*) begin
if (in[3])
out = 2'b11; // If bit 3 is 1, output is 3
else if (in[2])
out = 2'b10; // If bit 2 is 1, output is 2
else if (in[1])
out = 2'b01; // If bit 1 is 1, output is 1
else if (in[0])
out = 2'b00; // If bit 0 is 1, output is 0
else
out = 2'b00; // If none of the bits are 1, output is 0
end
endmodule
문제 : Priority Encoder with casez
- casez -> z는 dont care term 나타내는 자료형!
- ?도 가능은 하지만 z로 명시적 표현하자!
module top_module (
input [7:0] in,
output reg [2:0] pos );
always@(*)begin
casez(in)
8'bzzzzzzz1 : pos = 3'd0;
8'b??????10 : pos = 3'd1;
8'b?????100 : pos = 3'd2;
8'b????1000 : pos = 3'd3;
8'b???10000 : pos = 3'd4;
8'b??100000 : pos = 3'd5;
8'b?1000000 : pos = 3'd6;
8'b10000000 : pos = 3'd7;
default pos = 3'd0;
endcase
end
endmodule
문제 : avoiding latch
- 여러개를 조절하려면? - begin / end
module top_module (
input [15:0] scancode,
output reg left,
output reg down,
output reg right,
output reg up );
always @(*) begin
up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
case (scancode)
16'he06b : left = 1;
16'he072 : down = 1;
16'he074 : right = 1;
16'he075 : up = 1;
default :begin up = 0; down =0; left =0; right =0;
end
endcase
end
endmodule