Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- behavioral modeling
- vivado
- verilog
- gpio
- stop watch
- soc 설계
- Linked List
- LED
- structural modeling
- atmega 128a
- prescaling
- ATMEGA128A
- FND
- D Flip Flop
- java
- hc-sr04
- half adder
- dataflow modeling
- uart 통신
- Pspice
- ring counter
- Recursion
- DHT11
- i2c 통신
- Algorithm
- BASYS3
- KEYPAD
- Edge Detector
- test bench
- pwm
Archives
- Today
- Total
거북이처럼 천천히
Verilog RTL 설계(7월 16일 - 1, PIPO Shift Register) 본문
1. PIPO Shift Register (Parallel Input Parallel Output)
- 병렬 형태로 데이터를 입력 받아 저장하고, 레지스터에 저장된 데이터를 병렬 형태로 출력받는 구조를 갖는 레지스터
- 따라서 아래와 같이 게이트 레벨에서 회로를 구성할 수 있지만, 심각한 문제점을 갖는다.
- 문제점으로 지적되는 부분은 "WR 단자 값이 0일 경우, AND Gate으로 인해 Register를 구성하는 D Flip Flop의 입력값, D로 0이 들어가게 되고, 그 결과 Register에 저장되어 있던 데이터가 사라진다." 이다.
- 따라서 문제점을 해결하기 위해서 " WR 단자 값이 1일 때는 외부로부터 데이터를 입력 받아 레지스터에 저장하고, WR 단자 값이 0일 때는 외부로부터 데이터를 입력 받지 않고, 현 상태를 유지한다. " 처럼 동작하도록 설계하는 것이다.
1.1. WR 값이 0일 때, 레지스터에 저장된 데이터가 사라지는 문제점을 해결해보자.
- 먼저, D Flip Flop으로 구현한 8bit PIPO Register는 다음과 같은 구조로 표현 할 수 있다.
- ★★★★★★
Q) 그럼 어떻게 8bit Register으로 들어오는 데이터들을 Write_enable_p (WR)으로 제어할 수 있는가?
A) MUX를 통해 다음과 회로를 구성하고, MUX의 selector로 Write_enable_p를 연결하면 된다.
- 문제점에 대해서 다시 정리하자.
▶ PIPO Register는 출력 뿐만 아니라 입력쪽에서도 Common data bus를 사용한다.
▶Common data bus 를 사용하는 만큼 한 번에 하나의 register만 사용가능하다.
(사용 가능하다는 의미는 "Common data bus를 통해 read / write를 할 수 있다.)
▶따라서 하나의 메모리가 data bus를 사용 중이라면 나머지 메모리들은 data bus를 사용할 수 없다.
▶그래서 각각의 메모리가 Common data bus가 연결되는지 여부를 AND Gate로 구현했지만, write_enable_p 값이 0이면 데이터가 지워지는 문제점이 발생한다. - 해결책은 다음과 같다.
▶2X1 MUX를 입력 단자 부분에 연결한 뒤, 입력 단자에 각각 Common data bus, feedback을 연결한다.
▶MUX의 selector를 write_enable_p로 연결한다.
▶write_enable_p = 0 이면 현 상태 유지
▶write_enable_p = 1이면 common data bus와 연결되어 데이터를 입력 받는다.
- 8bit register를 여러 개 모일 경우 아래와 같이 회로를 구성할 수 있다.
- 8bit register의 입력 단자에 있는 MUX의 Selector를 모아 하나의 DEMUX로 관리가 가능하다.
- DEMUX의 selector을 통해 원하는 8bit register와 Common data bus를 연결 시켜 데이터를 Read / Write가 가능해진다.
- 이러한 관점에서 보았을 때, 결국 DEMUX의 selector는 메모리의 주소 (Address of memory)라 할 수 있다.
- ex) 4개의 8bit register가 존재한다면 DEMUX의 selector를 통해 다음과 같이 접근이 가능하다.
00이면 첫 번째 register, 01이면 두 번째 register, 10이면 세 번째 register, 11이면 4번째 register로 접근할 수 있는 것이다.
1.2. PIPO Register를 MUX를 통해 다시 구현하면 다음과 같다.
- Output Common data bus와 레지스터 연결을 제어하기 위해서 삼항 버퍼를 사용한다.
- Input Common data bus와 레지스터 연결을 제어하기 위해서 MUX를 사용한다.
- 여러 개의 8bit register 중 하나를 선택하여 접근하기 위해서는 DEMUX를 사용한다.
2. N bit PIPO Shift Register (Negative)
< Source >
module PIPO_N_bit_Register_Negative #(parameter N = 8) (
input clk, enable, reset_p,
input write_enable_p,
input read_enable_p,
input [N-1 : 0] input_data,
output [N-1 : 0] output_data);
reg [N-1 : 0] pipo_reg;
always @(negedge clk or posedge reset_p) begin
if(reset_p) pipo_reg = 0;
else if(enable) begin
if(write_enable_p) pipo_reg = input_data;
else pipo_reg = pipo_reg;
end
end
assign output_data = (read_enable_p)? pipo_reg : 'bz;
endmodule
< Test bench >
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/07/16 20:04:41
// Design Name:
// Module Name: tb_PIPO_N_bit_Register_n
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module tb_PIPO_N_bit_Register_n();
// set type of input / output
reg clk, enable, reset_p;
reg write_enable_p;
reg read_enable_p;
reg [6:0] input_data;
wire [6:0] output_data;
// create instance
PIPO_N_bit_Register_Negative #(.N(7)) DUT (
clk, enable, reset_p, write_enable_p, read_enable_p, input_data, output_data);
// data
parameter data = 7'b1010101;
// initialization of simulation.
initial begin
clk = 0; enable = 1; reset_p = 1; write_enable_p = 0; read_enable_p = 0; input_data = 0;
end
// set clock pulse
always #5 clk = ~clk;
// processing of simulation.
initial begin
#5;
// disable reset_p
reset_p = 0; #5;
// enable write_enable_p & Input data
write_enable_p = 1;
input_data = data; #10;
// disble write_enable_p & enable read_enable_p.
read_enable_p = 1;
write_enable_p = 0; #10;
// delay time : 10ns
#10;
// End of simulation
$finish;
end
endmodule
< Simulation >
3. N bit PIPO Shift Register (Negative, 2개 이상의 데이터를 레지스터에 저장)
< Test Bench >
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/07/16 20:04:41
// Design Name:
// Module Name: tb_PIPO_N_bit_Register_n
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module tb_PIPO_N_bit_Register_n();
// set type of input / output
reg clk, enable, reset_p;
reg write_enable_p;
reg read_enable_p;
reg [6:0] input_data;
wire [6:0] output_data;
// create instance
PIPO_N_bit_Register_Negative #(.N(7)) DUT (
clk, enable, reset_p, write_enable_p, read_enable_p, input_data, output_data);
// data
parameter data_0 = 7'b1010101;
parameter data_1 = 7'b0111110;
parameter data_2 = 7'b0010100;;
// initialization of simulation.
initial begin
clk = 0; enable = 1; reset_p = 1; write_enable_p = 0; read_enable_p = 0; input_data = 0;
end
// set clock pulse
always #5 clk = ~clk;
// processing of simulation.
initial begin
#5;
// disable reset_p
reset_p = 0; #5;
// enable write_enable_p & Input data
write_enable_p = 1;
input_data = data_0; #10;
// disble write_enable_p & enable read_enable_p.
read_enable_p = 1;
write_enable_p = 0; #10;
// delay time : 10ns
read_enable_p = 0;
#10;
// enable write_enable_p & Input data
write_enable_p = 1;
input_data = data_1; #10;
// disble write_enable_p & enable read_enable_p.
read_enable_p = 1;
write_enable_p = 0; #10;
// delay time : 10ns
read_enable_p = 0;
#10;
// enable write_enable_p & Input data
write_enable_p = 1;
input_data = data_2; #10;
// disble write_enable_p & enable read_enable_p.
read_enable_p = 1;
write_enable_p = 0; #10;
// delay time : 10ns
read_enable_p = 0;
#10;
// End of simulation
$finish;
end
endmodule
< Simulation >
- Clock Pulse이 Negative edge일 때 + write_enable = 1일 때, 레지스터에 데이터 저장 가능
- read_enable = 1일 때, (Clock Pulse와는 상관 없음) 레지스터에 저장된 데이터를 읽을 수 있다.
4. Output Common Data bus와 Input Common Data bus를 하나의 Common Data bus로 통합할 수 있다.
- read_enable 과 write_enable 의 값에 의해 레지스터에 Read와 Write 가 결정되기 때문에 하나의 Common Data bus로 통합할 수 있다.
- 따라서 Output Common Data bus와 Input Common Data bus를 하나의 Common Data bus로 통합하여 해당 Data bus을 통해 레지스터에 Read / Write 작업을 수행하기 때문에 통합된 Common Data bus는 양방향성 특성을 갖는다.
'RTL Design > Verilog RTL 설계' 카테고리의 다른 글
Verilog RTL 설계(7월 16일 - 2, Prescaler) (0) | 2024.07.17 |
---|---|
Verilog RTL 설계(7월 16일 - 2, SRAM) (0) | 2024.07.16 |
Verilog RTL 설계(7월 15일 - 4, PISO Shift Register) (0) | 2024.07.16 |
Verilog RTL 설계(7월 15일 - 3, SISO Register, SIPO Register) (2) | 2024.07.16 |
Verilog RTL 설계(7월 15일 - 2, Register, TestBench) (0) | 2024.07.15 |