APB接口的24小时计数器
//2022-3-19 soc设计
//APB接口的钟表计数器模块
//题目1:APB接口的模6计数器/模10计数器模块
// 设计内容:
//APB2.0 接口
//支持异步复位(低电平有效)
//支持软件同步复位(高电平有效)
//支持计数暂停(高电平有效)
//钟表计数器的显示按照每秒更新
//钟表计数器按照24小时循环计数
// 实验内容:
//完成RTL设计
//完成TESTBENCH设计
//完成FPGA演示
1.hour24_counter.v是带有 APB 接口24小时计数器,作为APB_slave
2.Timer24是计数信号,组成:{8’d0,hour_h[4:0],hour_l[4:0],minute_h[4:0],minute_h[4:0],second_h[4:0],second_l[4:0]} 即8个0,和后面的24位时分秒钟
3.hour24_counter_tb 是hour24_counter的testbench
4.APB_Bridge.v是hour24_counter的master
5.seg_dec.v是七段数码管module
功能1:24小时计数,仿真结果如下
功能2:同步复位(高电平有效)res
异步复位(低电平有效)preset
功能3:计数暂停(高电平有效)
暂停的计数秒,比正常时间计数1秒时间长
功能4:写信号,写好地址,选择、使能、读写信号都为1 时,将数据写入timer24
功能5:读信号,写好地址,选择、使能信号都为1 ,读写信号为0时,将数据从timer24读出文章来源:https://www.toymoban.com/news/detail-405178.html
文章来源地址https://www.toymoban.com/news/detail-405178.html
在这里插入代码片
// 2022-3-21 verilog学习
// 24小时计数器 秒:0-59循环,分:0-59 循环,时:0-24循环,当23:59:59时,重新初始化
//2022-3-19 soc设计
//APB接口的钟表计数器模块
//题目1:APB接口的模6计数器/模10计数器模块
// 设计内容:
//APB2.0 接口
//支持异步复位(低电平有效)
//支持软件同步复位(高电平有效)
//支持计数暂停(高电平有效)
//钟表计数器的显示按照每秒更新
//钟表计数器按照24小时循环计数
// 实验内容:
//完成RTL设计
//完成TESTBENCH设计
//完成FPGA演示
`timescale 1ns/1ps
module hour24_counter(
pclk,
preset,
s_reset,//同步复位,高电平有效
pause,//计数暂停
paddr,//地址总线,
psel,//从译码器来的片选信号
penable,//使能信号
pwrite,//高电平:写 低电平:读
pwdata,//32位宽写
prdata,//32位宽读
timer24
);
input pclk;
input preset;
input s_reset;
input pause;
input[31:0] paddr;//地址总线,
input psel;//从译码器来的片选信号
input penable;//使能信号
input pwrite;//高电平:写 低电平:读
input[31:0] pwdata;//32位宽写
output[31:0] prdata;//32位宽读
output[31:0] timer24;
parameter frequency_pclk = 100; // 24MHz
reg[8:0] con_t; // 秒脉冲分频计数器 24M, 十进制24000000转换为2进制是25位
reg s_pulse; // 秒脉冲尖 pulse脉冲
reg[31:0] timer24; // always中赋值需要reg型
wire[31:0] paddr;//地址线,再在此设为学号:216189
reg[31:0] prdata;//32位宽读
wire wr;//写
wire rd;//读
reg[31:0] REG_A;//模拟寄存器
reg[31:0] REG_B;//模拟寄存器
//------------ 读写功能 ---------------------
assign wr = psel & pwrite & penable;
assign rd = psel & (~pwrite) & penable;
always@(posedge pclk or negedge preset or posedge rd) begin // 敏感变量
if(rd==1)begin
case(paddr)
32'h216189 : prdata<=timer24;
//REG_A_ID : prdatanxt = REG_A;
//REG_B_ID : prdatanxt = REG_B;
//……寄存器的地址
endcase
end
end
// or posedge pause
always@(posedge pclk or negedge preset) begin // 敏感变量
if(!preset) begin
con_t <= 0; // 复位下降沿,时钟计数清零
s_pulse <= 0; // 秒脉冲清零
timer24<=0;
end
else if(s_reset==1'b1) begin
con_t <= 0; // 复位下降沿,时钟计数清零
s_pulse <= 0; // 秒脉冲清零
timer24 <= 0;
end
else if(wr)begin//写数据有效
case(paddr)
32'h216189 : timer24<=pwdata;
//REG_A_ID : prdatanxt = REG_A;
//REG_B_ID : prdatanxt = REG_B;
//……寄存器的地址
default : timer24 <= timer24;
endcase
end
else if(pause==1)begin
timer24<=timer24;
end
else begin
//'''''秒脉冲分频计数器''''' 板子时钟频率24M,即1s中24M个脉冲
if(con_t == frequency_pclk-1) begin // 时钟计数周期为24M, 0-23999999,到周期清零
con_t <= 0;
end
else begin
con_t <= con_t+9'd1;
end
//'''''秒脉冲尖'''''
if(con_t == 0)begin // 1s中24M个脉冲,到第0个脉冲,秒脉冲 = 1
s_pulse <= 1;
end
else begin
s_pulse <= 0;
end
//'''''秒计数'''''
if(s_pulse==1) begin
//'''''秒计数di'''''
if(timer24[3:0] == 9) begin // 0-59循环秒计数
timer24[3:0] <= 0;
timer24[7:4] <= timer24[7:4] + 4'd1;
end
else begin
timer24[3:0] <= timer24[3:0] +4'd1;//秒计数
end
//'''''秒计数gao''''
if((timer24[7:4]>=5)&(timer24[3:0] == 9))begin
timer24[7:4] <= 0; timer24[3:0] <= 0;
timer24[11:8] <= timer24[11:8] + 4'd1;
end
//'''''分计数di'''''
if((timer24[11:8]==9)&(timer24[7:4]>=5)&(timer24[3:0] == 9))begin
timer24[7:4] <= 0; timer24[3:0] <= 0;
timer24[11:8] <= 0; timer24[15:12] <= timer24[15:12] + 4'd1;
end
//'''''分计数gao'''''
if((timer24[15:12]>=5)&(timer24[11:8]==9)&(timer24[7:4]>=5)&(timer24[3:0] == 9))begin
timer24[7:4] <= 0; timer24[3:0] <= 0;
timer24[11:8] <= 0; timer24[15:12] <= 0;
timer24[19:16] <= timer24[19:16] + 4'd1;
end
//'''''时计数di'''''
if((timer24[19:16]==9)&(timer24[15:12]>=5)&(timer24[11:8]==9)&(timer24[7:4]>=5)&(timer24[3:0] == 9))begin
timer24[7:4] <= 0; timer24[3:0] <= 0;
timer24[11:8] <= 0; timer24[15:12] <= 0;
timer24[19:16] <= 0; timer24[23:20] <= timer24[23:20] + 4'd1;
end
//'''''时计数gao'''''
if((timer24[23:20]==2)&(timer24[19:16]==3)&(timer24[15:12]>=5)&(timer24[11:8]==9)&(timer24[7:4]>=5)&(timer24[3:0] == 9))begin
timer24[7:4] <= 0; timer24[3:0] <= 0;
timer24[11:8] <= 0; timer24[15:12] <= 0;
timer24[19:16] <= 0; timer24[23:20] <= 0;
end
end
end
end
endmodule
// testbench 测试台
module hour24_counter_tb;
reg pclk,preset,pause,s_reset;
reg[31:0] paddr;//地址总线
reg psel;//从译码器来的片选信号
reg penable;//使能信号
reg pwrite;//高电平:写 低电平:读
reg[31:0] pwdata;//32位宽写
wire[31:0] prdata;//32位宽读
wire[31:0] timer24;//秒计数低
hour24_counter hour24_counter(
.pclk(pclk),
.preset(preset),
.s_reset(s_reset),
.pause(pause),
.paddr(paddr),//地址总线,
.psel(psel),//从译码器来的片选信号
.penable(penable),//使能信号
.pwrite(pwrite),//高电平:写 低电平:读
.pwdata(pwdata),//32位宽写
.prdata(prdata),//32位宽读
.timer24(timer24)
);
initial begin
//preset==0,//异步复位,低电平有效//+时钟上升沿
//res==1,//同步,高电平有效
#0 pclk=0; preset=0; pause=0;s_reset=0;
psel=0; pwrite=0; penable=0;
paddr=0; pwdata=0;//初始化
#17 preset=1; // 过17ns,时钟复位解除
#50 s_reset=1;
#100 s_reset=0;
#300 pause=1;//暂停时钟,高电平有效
#350 pause=0;//接触时钟暂停
#900 preset=0;
#920 preset=1;
#1500 s_reset=1;
#1520 s_reset=0;
#2000 psel=1;paddr=32'h216189;pwdata={8'b0,4'd2,4'd3,4'd5,4'd9,4'd5,4'd6};
#2010 pwrite=1;
#2020 penable=1;//完成一次写操作
#2200 psel=0;paddr=0;pwdata=0;
#2230 penable=0;pwrite=0;
#3500 psel=1;
#3510 penable=1;paddr=32'h216189;
#3520 penable=0;//完成一次读操作
#3550 psel=0;
#7000 $stop;
end
always #5 pclk <= ~pclk; // 以10ns为周期的时钟
endmodule
在这里插入代码片
//-----------------------------------------------------------------------------------------------
// Copyright :
// File Name : APB_Bridge
// Author : Luk.wj
// Create : 2020.12.14
// Revise : 2021.12.20
// Description : APB_Bridge的作用是将主设备的访问信号转化成APB总线信号访问从设备
//-----------------------------------------------------------------------------------------------
/* State */
`define Idle 2'b00//空闲
`define Setup 2'b01//建立
`define Access 2'b10//可用
module APB_Bridge (
PCLK,
Prst,
Haddr,
Hwdata,
Hwrite,
Hen,
Prdata_m,
Paddr,
Pen,
Pwrite,
Pwdata,
Hrdata,
Hready,
PSEL0,
PSEL1,
PSEL2,
PSEL3
);
input PCLK;
input Prst;
/* AHB_Master */
input Hwrite;
input Hen;
input [31:0] Haddr;
input [31:0] Hwdata;
output reg Hready;
output reg [31:0] Hrdata;
/* APB_Slave */
input [31:0] Prdata_m;
output reg Pen;
output reg Pwrite;
output reg PSEL0;
output reg PSEL1;
output reg PSEL2;
output reg PSEL3;
output reg [31:0] Pwdata;
output reg [31:0] Paddr;
reg [1:0] APB_State; //APB状态参数
reg [23:0] addr_d; //截取总线地址的前24位选择从设备
/* 四个从设备内部变量 */
reg Hsel0;
reg Hsel1;
reg Hsel2;
reg Hsel3;
/* Read Data */
always @(*) begin
if (!Prst) Hrdata = 32'h0;
else Hrdata = Prdata_m;
end
/* Slave Select */
always @(*) begin
addr_d = Haddr[31:8];
Hsel0 = 1'b0;
Hsel1 = 1'b0;
Hsel2 = 1'b0;
Hsel3 = 1'b0;
case (addr_d)
24'h0000_00: Hsel0 = 1'b1;
24'h0000_01: Hsel1 = 1'b1;
24'h0000_02: Hsel2 = 1'b1;
24'h0000_03: Hsel3 = 1'b1;
default: begin
Hsel0 = 1'b0;
Hsel1 = 1'b0;
Hsel2 = 1'b0;
Hsel3 = 1'b0;
end
endcase
end
/* APB FSM */
always @(posedge PCLK or negedge Prst) begin
if (!Prst) begin
//AHB_Master
Hready <= 1'b0;
//APB_Slave
APB_State <= `Idle;
PSEL0 <= 1'b0;
PSEL1 <= 1'b0;
PSEL2 <= 1'b0;
PSEL3 <= 1'b0;
Pen <= 1'b0;
Pwrite <= 1'b0;
Pwdata <= 32'b0;
Paddr <= 32'b0;
end
else begin
case (APB_State)
`Idle: begin
if (Hen) begin
APB_State <= `Setup;
PSEL0 <= Hsel0;
PSEL1 <= Hsel1;
PSEL2 <= Hsel2;
PSEL3 <= Hsel3;
Pwrite <= Hwrite;
Paddr <= Haddr;
Pwdata <= Hwdata;
Hready <= 1'b0;
end
end
`Setup: begin
APB_State <= `Access;
Pen <= 1'b1;
Hready <= 1'b0;
end
`Access: begin
APB_State <= `Idle;
Pen <= 1'b0;
PSEL0 <= 1'b0;
PSEL1 <= 1'b0;
PSEL2 <= 1'b0;
PSEL3 <= 1'b0;
Hready <= 1'b1;
end
default: APB_State <= `Idle;
endcase
end
end
endmodule
在这里插入代码片
//2022-3-16
//七段数码管
`timescale 1ns/10ps
module seg_dec(
num,
a_g
);
input[3:0] num;
output[6:0] a_g;
reg[6:0] a_g;
//reg[3:0] num;
always@(num)begin
case(num)
//*****************abc-defg******哪个亮那个显示1
4'd0:begin a_g<=7'b111_1110;end//a_g-->{abcdefg}
4'd1:begin a_g<=7'b011_0001;end
4'd2:begin a_g<=7'b110_1101;end
4'd3:begin a_g<=7'b111_1001;end
4'd4:begin a_g<=7'b011_0011;end
4'd5:begin a_g<=7'b101_1011;end
4'd6:begin a_g<=7'b101_1111;end
4'd7:begin a_g<=7'b111_0000;end
4'd8:begin a_g<=7'b111_1111;end
4'd9:begin a_g<=7'b111_1011;end
default:begin a_g<=7'b000_0001;end
endcase
end
endmodule
//testbench
/*
module seg_dec_tb;
seg_dec seg_dec(
.num{},
.a_g()
);
endmodule
补码转换代码设计
七段译码代码设计
位拼接语句
case和default 的处理
*/
到了这里,关于APB接口的24小时钟表计数器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!