specparam t_ACS = 8; // Chip select access time
specparam t_CLZ = 2; // Chip select to output in low-z
// Parameters for the write cycle
specparam t_WC = 7; // Write cycle time
specparam t_CW = 5; // Chip select to end of write
specparam t_AW = 5; // Adress valid to end of write
//Module path timing specifications
(addr *> data) = t_AA; // Verified in simulation
(CS_b *> data) = (t_ACS, t_ACS, t_CHZ);
(OE_b *> data) = (t_OE, t_OE, t_OHZ); // Verified in simulation
//Timing checks (Note use of conditioned events for the address setup,
//depending on whether the write is controlled by the WE_b or by CS_b.
//Address setup before write enabled
$setup (addr, negedge WE_b &&& CS_b == 0, t_AS);
$setup (addr, negedge CS_b &&& WE_b == 0, t_AS);
//Width of write pulse
$width (negedge WE_b, t_WP);
//Data hold from end of write
$hold (data, posedge WE_b &&& CS_b == 0, t_DH);
$hold (data, posedge CS_b &&& WE_b == 0, t_DH);
//Chip sel to end of write
$setup (CS_b, posedge WE_b &&& CS_b == 0, t_CW);
$width (negedge CS_b &&& WE_b == 0, t_CW);
endspecify
//*/
reg[word_size -1: 0] write_probe;
case(col_addr)
0: write_probe = RAM_col0[ row_addr];
1: write_probe = RAM_col1[ row_addr];
2: write_probe = RAM_col2[ row_addr];
3: write_probe = RAM_col3[ row_addr];
endmodule
module test_SRAM_with_Con ();
parameter word_size = 8;
parameter addr_size = 11;
parameter mem_depth = 128;
// Three-state, bi-directional bus
wire [word_size -1: 0] data_bus = send? data_to_memory: Hi_Z_pattern;
wire [word_size -1: 0] data_from_memory = recv? data_bus: Hi_Z_pattern;
SRAM_with_Con M1 (data_bus, addr, Rdy, ADS_b, R_W, clk, reset); // UUT
// Non-Zero delay test: Write walking ones to memory
initial begin
ADS_b = 1;
R_W = 0;
send = 0;
recv = 0;
for (col= 0; col <= num_col-1; col = col +1) begin
data_to_memory =initial_pattern;
for (row = 0; row <= mem_depth-1; row = row + 1) begin
@ (negedge clk);
end
end
end
// Non-Zero delay test: Read back walking ones from memory
initial begin
#latency;
ADS_b = 1;
always @ (posedge M1.M1.WE_b, posedge M1.M1.CS_b)
case (M1.M1.col_addr)
0: write_probe = M1.M1.RAM_col0[M1.M1.row_addr];
1: write_probe = M1.M1.RAM_col1[M1.M1.row_addr];
2: write_probe = M1.M1.RAM_col2[M1.M1.row_addr];
3: write_probe = M1.M1.RAM_col3[M1.M1.row_addr];
Problem 8-10
module Prog_Lock_System (
output Ready, Reprogramming, Enter_kst, Prog_mode, Invalid_key, Unlock,
input [3: 0] Row,
input mode, clock, reset
Prog_Lock M2 (
.Ready(Ready),
.Reprogramming(Reprogramming),
.Enter_kst(Enter_kst),
module Prog_Lock (
output Ready, Reprogramming, Enter_kst, Prog_mode, Invalid_key, unlock,
input [3: 0] code, input mode, kst, clock, reset
);
Control_Unit M0 (
Ready, Reprogramming, Enter_kst, Prog_mode, Invalid_key, unlock, rst_ks_ctr, rst_ks_reg,
rst_T_ctr, rst_flg, set_flg,
inc_T_ctr, inc_ks_ctr, ld_code, ld_new_key, mode, kst, Tout, flg, rekey, key, ks_max1, ks_max2,
clock, reset
);
Datapath_Unit M1 (
parameter S_invalid = 3’d4;
reg [2: 0] state, next_state;
assign Prog_mode = (state == S_prog);
always @ * begin
rst_ks_ctr = 0;
rst_ks_reg = 0;
rst_T_ctr = 0;
rst_flg = 0;
set_flg = 0;
inc_T_ctr = 0;
inc_ks_ctr = 0;
S_normal: if (Tout) begin next_state = S_idle; do_resets; end
else begin
inc_T_ctr = 1;
if (ks_max1) begin
if (flg) begin next_state = S_idle; ld_new_key = 1; do_resets; end
rst_T_ctr = 1;
rst_flg = 1;
end
endtask
endmodule
module Datapath_Unit (
output Tout, output reg flg, output rekey, key, ks_max1, ks_max2,
input [3: 0] code, input mode, rst_ks_ctr, rst_ks_reg, rst_T_ctr, rst_flg, set_flg, inc_T_ctr,
inc_ks_ctr, ld_code,
ld_new_key, clock, reset
);
always @ (posedge clock)
if (reset)
begin ks_ctr <= 0; ks_reg <= 0; T_ctr <= 0; flg <= 0; end
else begin
if (rst_ks_ctr) ks_ctr <= 0;
assign rekey = (ks_reg == prog_key);
assign Tout = (T_ctr == Tmax);
assign ks_max1 = (ks_ctr == max1);
assign ks_max2 = (ks_ctr == max2);
assign Valid = ((state == S_1) || (state == S_2) || (state == S_3) || (state == S_4)) && Row;
// Does not matter if the row signal is not the debounced version.
// Assumed to settle before it is used at the clock edge
always @ (Row, Col)
case ({Row, Col})
8’b0100_0100: Code = 10; // A
8’b0100_1000: Code = 11; // B
8’b1000_0001: Code = 12; // C
8’b1000_0010: Code = 13; // D
8’b1000_0100: Code = 14; // E
8’b1000_1000: Code = 15; // F
default: Code = 0; // Arbitrary choice
endcase
// Assert all rows
S_0: begin Col = 4’hf; if (S_Row) next_state = S_1; end
// Assert col 0
S_1: begin Col = 1; if (Row) next_state = S_5; else next_state = S_2; end
// Assert col 1
S_2: begin Col = 2; if (Row) next_state = S_5; else next_state = S_3; end
// Assert col2
reg A_Row;
// Two stage pipeline synchronizer, synchronous reset
always @ (negedge clock) begin
if (reset == 1’b1) begin A_Row <= 0; S_Row <= 0; end
// Combinational logic for key assertion
Row[0] = Key[0] && Col[0] || Key[1] && Col[1] || Key[2] && Col[2] || Key[3] && Col[3];
Row[1] = Key[4] && Col[0] || Key[5] && Col[1] || Key[6] && Col[2] || Key[7] && Col[3];
Row[2] = Key[8] && Col[0] || Key[9] && Col[1] || Key[10] && Col[2] || Key[11] && Col[3];
Row[3] = Key[12] && Col[0] || Key[13] && Col[1] || Key[14] && Col[2] || Key[15] && Col[3];
end
endmodule
reg clock, reset;
reg [15: 0] Key;
always @ (Key) begin // “one-hot” code for pressed key
case (Key)
16’h0000: Pressed = None;
16’h0001: Pressed = Key_0;
16’h0002: Pressed = Key_1;
16’h1000: Pressed = Key_C;
16’h2000: Pressed = Key_D;
16’h4000: Pressed = Key_E;
16’h8000: Pressed = Key_F;
default: Pressed = None;
endcase
end
Prog_Lock_System M0 ( ready, Reprogramming, Enter_kst, Prog_mode, Invalid_key, Unlock,
join
initial fork
mode = 1;
#1260 mode = 0;
join
end
#4600 Key = 16’h8000; //f
#4700 Key = 0;
#4800 Key = 16’h0001; //0
#4900 Key = 0;
#5000 Key = 16’h0002; //1
#5100 Key = 0;
/*#4000 Key = 0;
#4200 Key = 16’h0100; //e
#4300 Key = 0;
#4400 Key = 16’h0200; //f
#4500 Key = 0;
Problem 8-11
module Row_Signal (Row, Key, Col);
output [3: 0] Row;
input [15: 0] Key;
input [3: 0] Col;
reg Row;
// Scan for row of the asserted key
/*
// Test Bench
module test_Hex_Keypad_Grayhill_072 ();
wire [5: 0] state;
wire [6: 0] Cathode;
wire [3: 0] Col;
reg [15: 0] Key;
integer j, k;
reg [39: 0] Pressed;
parameter [39: 0] Key_0 = “Key_0”;
parameter [39: 0] Key_1 = “Key_1”;
wire stack0 = UUT.M2.stack[0]; // Probes of the stack
wire stack1 = UUT.M2.stack[1];
wire stack2 = UUT.M2.stack[2];
wire stack7 = UUT.M2.stack[7];
always @ (Key) begin
case (Key)
16’h0000: Pressed = None;
16’h0001: Pressed = Key_0;
16’h0002: Pressed = Key_1;
16’h0004: Pressed = Key_2;
16’h0008: Pressed = Key_3;
16’h0010: Pressed = Key_4;
16’h0020: Pressed = Key_5;
16’h0040: Pressed = Key_6;
default: Pressed = None;
endcase
end
TOP_Keypad_FIFO UUT
(state, Cathode, Col, Left_anode, Right_anode, valid, empty, full, Row, read, clock,
reset);
//Hex_Keypad_Grayhill_072 M1(Code, Col, Valid, Row, S_Row, clock);
initial begin for (k = 0; k <= 1; k = k+1) begin Key = 0; #30 for (j = 0; j <= 16; j = j+1)
begin
end
end
endmodule
module TOP_Keypad_FIFO (state, Cathode, Col, Left_anode, Right_anode, valid,
empty, full, Row, read, clk, reset);
output [5: 0] state;
wire [3: 0] Code, Code_out;
wire S_Row;
wire valid;
wire [6: 0] Left_out, Right_out;
wire clk_slow, clk_display;
wire read_fifo, read_synch;
Synchronizer M0 (
.S_Row(S_Row),
FIFO M2 (
.Data_out(Code_out),
.Data_in(Code),
.stack_empty(empty),
.Right_out(Right_out),
.Code_in(Code_out));
Display_Mux_3_4 M5 (
.Cathode(Cathode),
.Left_anode(Left_anode),
.clk_in(clk),
.reset(reset));
Toggle M8 (
.toggle_out (read_fifo),
.toggle_in (read_synch),
.clk(clk_slow),
.reset(reset));
endmodule