Time-multiplexing quad seven segment display on Nexys 4

M

Maj55

Guest
I am working on a verilog code where I am running on Nexys 4 for led multiplexing. I am able to run 0 - 9 on 4 7 segment units. How can I make it time-multiplexed where each seven-segment unit is illuminated before/after units adjacent to it?

here is my code:

`timescale 1ns / 1ps
module sseg_pwm(
input wire clk,
input wire [3:0] value,
input wire [WIDTH-1:0] duty_cycle,
output wire seg0, seg1, seg2, seg3, seg4, seg5, seg6, dp,
output wire an0, an1, an2, an3
);

parameter MAX_VAL = 'd10;
parameter WIDTH = 'd4;

reg [WIDTH-1:0] pwm, next_pwm;
reg [6:0] sseg;

//PWM counter
always @(posedge clk) pwm <= next_pwm;

always @(*) next_pwm = (pwm == MAX_VAL) ? 'd0 : pwm + 1;

assign {seg6, seg5, seg4, seg3, seg2, seg1, seg0, dp} = (pwm < duty_cycle) ? sseg : 8'b11111111;
reg [23:0] count;
always @(posedge clk) count <= count+24'h1;
wire counter = &count;

// BCD->SSEG
reg [3:0] BCD_new, BCD_old;
always @(posedge clk) if(counter) BCD_new <= (BCD_new==4'h9 ? 4'h0 : BCD_new+4'h1);
always @(posedge clk) if(counter) BCD_old <= BCD_new;
wire [3:0] BCD = (count[23] | pwm[4]) ? BCD_new : BCD_old;
wire pwm;//reg [4:0] pwm; wire [4:0] pwm

always @(*)
case(BCD)
4'h0: sseg = 8'b10000001;
4'h1: sseg = 8'b01001001;
4'h2: sseg = 8'b01100001;
4'h3: sseg = 8'b01100011;
4'h4: sseg = 8'b00110011;
4'h5: sseg = 8'b00100101;
4'h6: sseg = 8'b00000101;
4'h7: sseg = 8'b11110001;
4'h8: sseg = 8'b00000001;
4'h9: sseg = 8'b00100001;

default: sseg = 8'b00000000;
endcase
 
Edited working code below:

`timescale 1ns / 1ps
module sseg_pwm(
input wire clk,
input wire [WIDTH-1:0] duty_cycle,
output wire seg0, seg1, seg2, seg3, seg4, seg5, seg6, dp,
output wire an0, an1, an2, an3
);

//parameter MAX_VAL = 'd10;
parameter WIDTH = 'd4;
reg [6:0] sseg;
assign {seg6, seg5, seg4, seg3, seg2, seg1, seg0, dp} = ( duty_cycle) ? sseg : 8'b11111111;
reg [23:0] count;
always @(posedge clk) count <= count+24'h1;
wire counter = &count;
// BCD->SSEG
reg [3:0] BCD_new, BCD_old;
always @(posedge clk) if(counter) BCD_new <= (BCD_new==4'h9 ? 4'h0 : BCD_new+4'h1);
always @(posedge clk) if(counter) BCD_old <= BCD_new;
wire [3:0] BCD = (count[23]) ? BCD_new : BCD_old;
reg [3:0] BCD = (count[23]) ? BCD_new : BCD_old;

always @(*)
case(BCD)
4'h0: sseg = 8'b10000001;
4'h1: sseg = 8'b01001001;
4'h2: sseg = 8'b01100001;
4'h3: sseg = 8'b01100011;
4'h4: sseg = 8'b00110011;
4'h5: sseg = 8'b00100101;
4'h6: sseg = 8'b00000101;
4'h7: sseg = 8'b11110001;
4'h8: sseg = 8'b00000001;
4'h9: sseg = 8'b00100001;

default: sseg = 8'b00000000;
endcase

endmodule
 
On 9/16/2014 7:09 PM, Maj55 wrote:
> I am working on a verilog code where I am running on Nexys 4 for led multiplexing. I am able to run 0 - 9 on 4 7 segment units. How can I make it time-multiplexed where each seven-segment unit is illuminated before/after units adjacent to it?

I think I understand your code and it looks ok but it only has one digit
input, 'value'. You either need to input multiple digits or you need to
externally time multiplex the one digit input for multiple digits.

In either case you need a digit counter which will be used to select the
digit displayed and mux that digit into 'value' either inside this
module or provide the digit counter and mux the value input. This
counter must be decoded to assert one of the four 'an' outputs. Simple,
no?

Wait, I can't find where you use "value" anywhere. The display is
driven by the BCD counter instead. Well figure out where your digit
info is coming from and multiplex it into the seven segment decoder.
You seem to be doing that now with two digits, BCD_old and BCD_new. Use
that same condition to drive two separate an lines and you will see the
two numbers in two different digits on the display. Uh, I don't see
where you are driving an0 anywhere...

Rick


here is my code:

`timescale 1ns / 1ps
module sseg_pwm(
input wire clk,
input wire [3:0] value,
input wire [WIDTH-1:0] duty_cycle,
output wire seg0, seg1, seg2, seg3, seg4, seg5, seg6, dp,
output wire an0, an1, an2, an3
);

parameter MAX_VAL = 'd10;
parameter WIDTH = 'd4;

reg [WIDTH-1:0] pwm, next_pwm;
reg [6:0] sseg;

//PWM counter
always @(posedge clk) pwm <= next_pwm;

always @(*) next_pwm = (pwm == MAX_VAL) ? 'd0 : pwm + 1;

assign {seg6, seg5, seg4, seg3, seg2, seg1, seg0, dp} = (pwm < duty_cycle) ? sseg : 8'b11111111;
reg [23:0] count;
always @(posedge clk) count <= count+24'h1;
wire counter = &count;

// BCD->SSEG
reg [3:0] BCD_new, BCD_old;
always @(posedge clk) if(counter) BCD_new <= (BCD_new==4'h9 ? 4'h0 : BCD_new+4'h1);
always @(posedge clk) if(counter) BCD_old <= BCD_new;
wire [3:0] BCD = (count[23] | pwm[4]) ? BCD_new : BCD_old;
wire pwm;//reg [4:0] pwm; wire [4:0] pwm

always @(*)
case(BCD)
4'h0: sseg = 8'b10000001;
4'h1: sseg = 8'b01001001;
4'h2: sseg = 8'b01100001;
4'h3: sseg = 8'b01100011;
4'h4: sseg = 8'b00110011;
4'h5: sseg = 8'b00100101;
4'h6: sseg = 8'b00000101;
4'h7: sseg = 8'b11110001;
4'h8: sseg = 8'b00000001;
4'h9: sseg = 8'b00100001;

default: sseg = 8'b00000000;
endcase

--

Rick
 

Welcome to EDABoard.com

Sponsor

Back
Top