# HW2 BCD to Decimal Decoder with Preset/Reset
---
[TOC]
## 1.實驗目的
由下圖所指定的真值表,來完成一個BCD to Decimal Decoder with Preset/Reset電路。

**圖:真值表**
## 2.電路撰寫與驗證
根據上圖的真值表,進行由輸入BCD對應到輸出Decimal的運算,並使用case寫法,運算後先丟進out_reg腳位暫存,在確認完Priority後再輸出。
而Reset/Preset/out_reg的Priority順序,使用了if-else電路決定輸出結果為何。
Priority : Reset > Preset >out_reg
以下是RTL與testbench的Code:
### RTL
```
module bcd_to_decimal_decoder (
Reset_n, //Reset the circult to 0
Preset, //Preset the circult
bcd_in, //BCD Input to decide decimal_out
decimal_out //Decimal Output
);
input Reset_n;
input Preset;
input [3:0] bcd_in;
output [9:0] decimal_out;
reg [9:0] decimal_out;
reg [9:0] out_reg; //output register to store compute value
always @(bcd_in) //BCD Input Computation
begin
case(bcd_in)
4'd0:
out_reg = 10'b1111111110;
4'd1:
out_reg = 10'b1111111101;
4'd2:
out_reg = 10'b1111111011;
4'd3:
out_reg = 10'b1111110111;
4'd4:
out_reg = 10'b1111101111;
4'd5:
out_reg = 10'b1111011111;
4'd6:
out_reg = 10'b1110111111;
4'd7:
out_reg = 10'b1101111111;
4'd8:
out_reg = 10'b1011111111;
4'd9:
out_reg = 10'b0111111111;
default:
out_reg = 10'b1111111111;
endcase
end
always@(*)
begin
if(!Reset_n) //Reset Primary
decimal_out = 10'd0;
else if (Preset) //Preset Secondoary
decimal_out = 10'b0000001111;
else //BCD Input Computation Last
decimal_out = out_reg;
end
endmodule
```
### testbench
```
`timescale 1ns / 10ps
module bcd_to_decimal_tb;
reg Reset_n;
reg Preset;
reg [3:0] data_in;
wire [9:0] dec_out;
initial
begin
$dumpfile("bcd_to_decimal.vcd");
$dumpvars(0,bcd_to_dec);
end
integer i;
initial
begin
$monitor("Reset_n = %b, Preset = %b, bcd_in = %b, decimal_out = %b",
Reset_n, Preset, data_in, dec_out);
#0 Reset_n = 1'b0; Preset = 1'b1; data_in = 4'd0; //Test Reset
#10 Reset_n = 1'b1; Preset = 1'b1; data_in = 4'd0; //Test Preset
for( i=0 ; i<16 ;i++)
begin
#10 Reset_n = 1'b1; Preset = 1'b0; data_in = i;
end
#10 $finish;
end
bcd_to_decimal_decoder bcd_to_dec(
.Reset_n(Reset_n),
.Preset(Preset),
.bcd_in(data_in),
.decimal_out(dec_out)
);
endmodule
```
### 電路驗證圖

**Reset_n驗證**

**Preset驗證**

**Input Computation驗證**
驗證結果皆與真值表相同
## 3.FPGA模擬
### A.波型模擬

1.Reset

2.Preset

3.BCD經過Decoder,運算成Decimal結果。
### B.Elaborate Design

**圖:Defalt Layout**

**圖:I/O Planning**

**圖:Floorplanning**
### C.Synthesis

**圖:synthesis後Layout**

**圖:Power**

**圖:Timing**

**圖:Area**
## 4.FPGA開發板模擬
xdc腳位配置為:
左變的兩顆Switch由左向右分別是Reset_n/Preset
右邊的四個Bottom由左至由分別為bcd_input的MSB到LSB
輸出則由PModA/PModB輸出至右邊的LED燈,由下往上分別為decimal_output的MSB到LSB
結果討論:

1.Reset_n=0, Preset=0,不論輸入,輸出皆為0

2.Reset_n=0, Preset=1,由於Reset的優先權更高,所以執行Reset功能,輸出0

3.Reset_n=1, Preset=1,由於Preset_n沒有啟動,故執行Preset功能,輸出00_0000_1111
**接下來的Reset_n=1, Preset=0,故結果將由bcd_in進行決定:**

a. bcd_in=0000(0), dec_out=11_1111_1110

b. bcd_in=0001(1), dec_out=11_1111_1101

c. bcd_in=0010(2), dec_out=11_1111_1011

d. bcd_in=0011(3), dec_out=11_1111_0111

e. bcd_in=0100(4), dec_out=11_1110_1111

f. bcd_in=0101(5), dec_out=11_1101_1111

g. bcd_in=0110(6), dec_out=11_1011_1111

h. bcd_in=0111(7), dec_out=11_0111_1111

i. dec_in=1000(8), dec_out=10_1111_1111

j. dec_in=1001(9), dec_out=01_1111_1111

k. dec_in=1010(10), dec_out=11_1111_1111(全亮)
(輸入10-15輸出結果皆為11_1111_1111,所以只顯示輸入10結果)
結果都與真值表相同!
## 5.實驗心得與討論
觀察下來,Schematic與我所設計的RTL一致,經由ROM先儲存由BCD計算出的Decimal結果,再由兩個MUX決定Reset/Preset/Decoder Compute的輸出Priority選擇。
Power方面,Core因為是小電路,只有0.034W
Timing因為是Combinational電路,所以沒有Slack的問題
Area因為是小電路,所以暫的總比例也很小。
並且也實際利用了FPGA開發版進行測試,讓我們操作完整的FPGA流程,及對開發版的使用上更加熟練,並增加對此電路的理解。
經過這次實驗下來,我認為可以嘗試去做不同的設計,並觀測不同設計做出來的結果誤差,並思考如何trade-off和最佳化是很重要的
## 6.參考文獻
https://www.ti.com/lit/ds/sdls109/sdls109.pdf