# 數位電路實驗暨 verilog 學習(二)
> 此章節接下來將實做簡易版的encoder與decoder其理論應用請自行查詢
# Decoder 解碼器
> decoder 類似查找表,module代碼如下
```
module decoder(x,e,y);
input [1:0] x ;
input e;
output reg[3:0] y;
always@(*) begin
if (e)
case(x)
2'b00 : y = 4'b1000;
2'b01 : y = 4'b0100;
2'b10 : y = 4'b0010;
2'b11 : y = 4'b0001;
default : y = 4'b0000;
endcase
else
assign y = 4'b0000;
end
endmodule
```
> sim.cpp
```
#include "verilated.h"
#include "verilated_vcd_c.h"
#include "obj_dir/Vdecoder.h"
//obj_dir/V(.v檔名稱).h
VerilatedContext* contextp = NULL;
VerilatedVcdC* tfp = NULL;
static Vdecoder* top;
// static V(.v檔名稱)* top
void step_and_dump_wave(){
top->eval();
contextp->timeInc(1);
tfp->dump(contextp->time());
}
void sim_init(){
contextp = new VerilatedContext;
tfp = new VerilatedVcdC;
top = new Vdecoder;
// top = new V(.v檔名稱)
contextp->traceEverOn(true);
top->trace(tfp, 0);
tfp->open("dump.vcd");
}
void sim_exit(){
step_and_dump_wave();
tfp->close();
}
int main() {
sim_init();
top->e = 0b0; top->x = 0b00; step_and_dump_wave();
top->x = 0b01; step_and_dump_wave();
top->x = 0b10; step_and_dump_wave();
top->x = 0b11; step_and_dump_wave();
top->e = 0b1; top->x = 0b00; step_and_dump_wave();
top->x = 0b01; step_and_dump_wave();
top->x = 0b10; step_and_dump_wave();
top->x = 0b11; step_and_dump_wave();
sim_exit();
}
```
# Encoder 編碼器
> module code
```
module encoder(x,e,y);
input [3:0] x;
input e;
output reg [1:0] y;
always@(*)begin
if (e) begin
// statement 前都加begin
case(x)
4'b0001 : y = 2'b00;
4'b0010 : y = 2'b01;
4'b0100 : y = 2'b10;
4'b1000 : y = 2'b11;
default : y = 2'b00;
endcase
end
else y = 2'b00;
end
endmodule
```
> sim.cpp
```
#include "verilated.h"
#include "verilated_vcd_c.h"
#include "obj_dir/Vencoder.h"
VerilatedContext* contextp = NULL;
VerilatedVcdC* tfp = NULL;
static Vencoder* top;
void step_and_dump_wave(){
top->eval();
// eval函數調用則代表更新各訊號狀態
contextp->timeInc(1);
// 增加模擬時間,數字代表時間有多少個單位時間長
tfp->dump(contextp->time());
// 把波形丟到vcd檔
}
void sim_init(){
contextp = new VerilatedContext;
tfp = new VerilatedVcdC;
top = new Vencoder;
contextp->traceEverOn(true);
//啟動追蹤
top->trace(tfp, 0);
tfp->open("dump.vcd");
}
void sim_exit(){
step_and_dump_wave();
tfp->close();
}
int main (){
sim_init();
top -> e = 0b0;
top -> x = 0b0001; step_and_dump_wave();
top -> x = 0b0010; step_and_dump_wave();
top -> x = 0b0100; step_and_dump_wave();
top -> x = 0b1000; step_and_dump_wave();
top -> e = 0b1;
top -> x = 0b0001; step_and_dump_wave();
top -> x = 0b0010; step_and_dump_wave();
top -> x = 0b0100; step_and_dump_wave();
top -> x = 0b1000; step_and_dump_wave();
sim_exit();
}
```
>Terminal
```
verilator --cc --trace encoder.v --exe sim.cpp
```
```
make -j -C obj_dir/ -f Vencoder.mk Vencoder
```
```
./obj_dir/Vencoder
```
```
gtkwave dump.vcd
```
# 四對二優先編碼器
> module code
```
module pencoder (x,e,y);
input [3:0] x;
input e;
output reg [1:0] y;
integer i;
integer count;
always@(*)begin // 4
count = 0;
y = 2'b00;
if (e)begin // 3
for(i=0;i<=3;i++)begin//2
if(x[i]==1) begin//1
count = i;
end//1
else y = 2'b00;
end//2
case (count)
0: y = 2'b00;
1: y = 2'b01;
2: y = 2'b10;
3: y = 2'b11;
default: y = 2'b00;
endcase
end //3
end //4
endmodule
```
> sim.cpp
```
#include "verilated.h"
#include "verilated_vcd_c.h"
#include "obj_dir/Vpencoder.h"
VerilatedContext* contextp = NULL;
VerilatedVcdC* tfp = NULL;
static Vpencoder* top;
//更改
void step_and_dump_wave(){
top->eval();
// eval函數調用則代表更新各訊號狀態
contextp->timeInc(2);
// 增加模擬時間,數字代表時間有多少個單位時間長
tfp->dump(contextp->time());
// 把波形丟到vcd檔
}
void sim_init(){
contextp = new VerilatedContext;
tfp = new VerilatedVcdC;
top = new Vpencoder;
//更改
contextp->traceEverOn(true);
//啟動追蹤
top->trace(tfp, 0);
tfp->open("dump.vcd");
}
void sim_exit(){
step_and_dump_wave();
tfp->close();
}
int main (){
sim_init();
top -> e = 0b0;
top -> x = 0b0001; step_and_dump_wave();
top -> x = 0b0010; step_and_dump_wave();
top -> x = 0b0100; step_and_dump_wave();
top -> x = 0b1000; step_and_dump_wave();
top -> x = 0b1001; step_and_dump_wave();
top -> x = 0b0110; step_and_dump_wave();
top -> x = 0b0101; step_and_dump_wave();
top -> x = 0b0011; step_and_dump_wave();
top -> e = 0b1;
top -> x = 0b0001; step_and_dump_wave();
top -> x = 0b0010; step_and_dump_wave();
top -> x = 0b0100; step_and_dump_wave();
top -> x = 0b1000; step_and_dump_wave();
top -> x = 0b1001; step_and_dump_wave();
top -> x = 0b0110; step_and_dump_wave();
top -> x = 0b0101; step_and_dump_wave();
top -> x = 0b0011; step_and_dump_wave();
sim_exit();
}
```
實驗二到此結束,接下來到 : [實驗三](https://hackmd.io/@1p0_VOUHTXGcHlBU9A0OEA/SJac8k-oC)